UVa1218

来源:互联网 发布:xmlbar软件下载 编辑:程序博客网 时间:2024/06/05 05:30

题目链接

分析:

  • f[u][0]:u是服务器,u的父亲不是服务器,那么u的儿子可以是服务器,也可以不是
  • f[u][1]:u不是服务器,但是u的父亲是服务器,那么u的儿子一定不是服务器
  • f[u][2]:u不是服务器,u的父亲也不是服务器,那么u的儿子中恰好有一个是服务器

f[u][0]=sum{min(f[son][0] , f[son][1])}+1

f[u][1]=sum{f[son][2]}

f[u][2]=min{f[u][1]-f[son][2]+f[son][0]}

tip

网上的前辈说:f(u,2)初始值要设为无穷大,但是不要设成乱七八糟的东西,改成N就能A了
我:我不信。。。
半小时后,我:好吧,我信了。。。

//这里写代码片#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int INF=0x33333333;const int N=10003;struct node{    int x,y,nxt;};node way[N<<1];int n=0;int f[N][3],tot=0,st[N];void add(int u,int w){    tot++;    way[tot].x=u;way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;    tot++;    way[tot].x=w;way[tot].y=u;way[tot].nxt=st[w];st[w]=tot;}void dfs(int now,int fa){       f[now][0]=1; f[now][1]=0; f[now][2]=N;    //    for (int i=st[now];i;i=way[i].nxt)        if (way[i].y!=fa)        {            dfs(way[i].y,now);            f[now][0]+=min(f[way[i].y][1],f[way[i].y][0]);            f[now][1]+=f[way[i].y][2];        }    for (int i=st[now];i;i=way[i].nxt)        if (way[i].y!=fa)            f[now][2]=min(f[now][2],f[now][1]-f[way[i].y][2]+f[way[i].y][0]);}int main(){    while (scanf("%d",&n)!=EOF)    {        memset(st,0,sizeof(st)); tot=0;        for (int i=1;i<n;i++)        {            int u,w;            scanf("%d%d",&u,&w);            add(u,w);        }        dfs(1,-1);        printf("%d\n",min(f[1][0],f[1][2]));        scanf("%d",&n);        if (n==-1) break;    }    return 0;}
原创粉丝点击