题目描述
一个网络中有NNN个节点,由N−1N-1N−1条边连通,每个节点是服务器或者客户端。如果节点u是客户端,就意味着u所连接的所有点中有且仅有一台服务器。求最少要多少台服务器才能满足要求。
输入输出格式
输入格式
输入包含多组测试数据。对于每组数据,第一行是一个整数N(≤10000)N(\le10000)N(≤10000)。接下来N−1N-1N−1行,每行两个整数ai,bia_i,b_iai,bi,表示ai,bia_i,b_iai,bi有一条双向连通的边。除最后一组输入以外,每组数据以000结尾,最后一组数据以−1-1−1结尾。
输出格式
对于每组输入,仅输出一行,表示所需要的最小服务器台数。
树形dp
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <vector> 6 using namespace std; 7 const int maxn=1e5+5; 8 const int INF=1e9+5; 9 struct A 10 { 11 int v,next; 12 }e[maxn]; 13 int head[maxn],tot; 14 int d[maxn][3]; 15 int n,a,b; 16 template <class t>void red(t &x) 17 { 18 x=0; 19 int w=1; 20 char ch=getchar(); 21 while(ch<'0'||ch>'9') 22 { 23 if(ch=='-') 24 w=-1; 25 ch=getchar(); 26 } 27 while(ch>='0'&&ch<='9') 28 { 29 x=(x<<3)+(x<<1)+ch-'0'; 30 ch=getchar(); 31 } 32 x*=w; 33 } 34 void input() 35 { 36 freopen("input.txt","r",stdin); 37 //freopen("output.txt","w",stdout); 38 } 39 void add(int x,int y) 40 { 41 e[++tot].v=y; 42 e[tot].next=head[x]; 43 head[x]=tot; 44 } 45 void dfs(int u,int fa) 46 { 47 d[u][0]=1; 48 d[u][1]=0; 49 d[u][2]=INF; 50 for(int i=head[u];i;i=e[i].next) 51 { 52 int v=e[i].v; 53 if(v==fa) 54 continue; 55 dfs(v,u); 56 d[u][0]+=min(d[v][0],d[v][1]);//u 57 if(d[v][2]>=INF) 58 d[u][1]=INF; 59 else 60 d[u][1]+=d[v][2];//f 61 } 62 for(int i=head[u];i;i=e[i].next) 63 { 64 int v=e[i].v; 65 if(v==fa) 66 continue; 67 // if(d[v][2]<INF) 68 d[u][2]=min(d[u][2],d[u][1]+d[v][0]-d[v][2]); 69 } 70 } 71 int main() 72 { 73 //input(); 74 while(1) 75 { 76 red(n); 77 if(!n) 78 red(n); 79 if(n==-1) 80 break; 81 tot=0; 82 memset(head,0,sizeof(head)); 83 //memset(d,0x3f,sizeof(d)); 84 for(int i=1;i<n;++i) 85 { 86 red(a); 87 red(b); 88 add(a,b); 89 add(b,a); 90 } 91 dfs(1,0); 92 printf("%d\n",min(d[1][0],d[1][2])); 93 } 94 return 0; 95 }View Code