一共有三种状态:
1、d[u][0]:u是服务器,每个子结点可以是也可以不是。
2、d[u][1]:u不是服务器,但u的父亲是,u的子结点都不是服务器。
3、d[u][2]:u和u的父亲都不是服务器,u的子结点恰有一个是服务器。
三种状态的转移:
d[u][0]=∑min(d[v][0],d[v][1])+1
d[u][1]=∑d[v][2]
d[u][2]=min(d[u][1]−d[v][2]+d[v][0])
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1e4+5; 5 const int INF = 1e9; 6 7 vector<int> G[maxn],vertices; 8 int p[maxn],d[maxn][3]; 9 10 void dfs(int u,int fa){ 11 vertices.push_back(u); 12 p[u] = fa; 13 for(int i=0; i<G[u].size(); i++){ 14 int v = G[u][i]; 15 if(v!=fa) dfs(v,u); 16 } 17 } 18 19 int main(){ 20 int n; 21 while(scanf("%d",&n)==1){ 22 for(int i=0; i<n; i++) G[i].clear(); 23 for(int i=0; i<n-1; i++){ 24 int u,v; 25 scanf("%d%d",&u,&v); u--,v--; 26 G[u].push_back(v); 27 G[v].push_back(u); 28 } 29 vertices.clear(); 30 dfs(0,-1); 31 32 for(int i=vertices.size()-1; i>=0; i--){ 33 int u = vertices[i]; 34 d[u][0] = 1; d[u][1] = 0; 35 for(int i=0; i<G[u].size(); i++){ 36 int v = G[u][i]; 37 if(v==p[u]) continue; 38 d[u][0] += min(d[v][0],d[v][1]); 39 d[u][1] += d[v][2]; 40 if(d[u][0]>INF) d[u][0] = INF; 41 if(d[u][1]>INF) d[u][1] = INF; 42 } 43 44 d[u][2] = INF; 45 for(int i=0; i<G[u].size(); i++){ 46 int v = G[u][i]; 47 if(v==p[u]) continue; 48 d[u][2] = min(d[u][2],d[u][1]-d[v][2]+d[v][0]); 49 } 50 } 51 52 printf("%d ",min(d[0][0],d[0][2])); 53 scanf("%d",&n); 54 } 55 56 }