其他分享
首页 > 其他分享> > 保安站岗

保安站岗

作者:互联网

题目传送门

一道比较典型的树形\(DP\)吧。

最后取\(f[1][0][1]\)和\(f[1][1][1]\)中较小的一个就行。

一直卡在90分上过不了的原因:

enter image description here

enter image description here

认真看题!!!

竟然还有90分,出题人真良心。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,f[1505][2][2],ans;// 2->  0 1  表示i能不能被覆盖  
int head[1505],tot,w[1505];
struct edge{
    int node,next;
}e[3005];
void add(int x,int y)
{
    e[++tot].node=y;
    e[tot].next =head[x];
    head[x]=tot;
}
void dfs(int u,int fa)
{
    f[u][1][1]=w[u];    
    bool flag=0;
    int minn=0x7ffffff; 
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].node;
        if(v==fa) continue;
        dfs(v,u);
        
/*      f[u][0][0]=min(f[u][0][0],f[v][0][1]);
        f[u][0][1]=min(f[u][0][1],f[v][1][1]);
        f[u][1][1]=min(f[u][1][1],min(f[v][0][0],min(f[v][0][1],f[v][1][1]))+w[u]);
        minn=min(minn,f[v][1][1]);(水平倒退www)*/
        
        f[u][0][0]+=min(f[v][0][1],f[v][1][1]);
        minn=min(minn,f[v][1][1]-f[v][0][1]);
        if(f[v][1][1]>f[v][0][1])
         f[u][0][1]+=f[v][0][1];
        else f[u][0][1]+=f[v][1][1],flag=1;
        f[u][1][1]+=min(f[v][1][1],min(f[v][0][1],f[v][0][0])); 
    }   
    
/*  f[u][0][1]=min(f[u][0][1],minn);
    if(!flag) f[u][0][0]=0,f[u][1][1]=w[u]; */
    //只要儿子中有一个安排了保安,u就会被覆盖到 
    //如果儿子中都没有安排保安,那么就选一个替换  
    if(!flag) f[u][0][1]+=minn; 
}
int main()
{
//  memset(f,0x7f,sizeof(f));
    scanf("%d",&n);
    int x,y,k;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&x); 
        scanf("%d%d",&w[x],&k);   
        for(int j=1;j<=k;++j) 
        {
            scanf("%d",&y);    
            add(x,y); add(y,x); 
        }
    } 
    dfs(1,0);                  
    ans=min(f[1][1][1],f[1][0][1]); 
    printf("%d\n",ans);  
    return 0;
}

标签:minn,min,int,tot,儿子,include,保安,站岗
来源: https://www.cnblogs.com/karryW/p/11477850.html