pku3659 Cell Phone Network
http://poj.org/problem?id=3659
树状DP,树的最小点覆盖
1 #include <stdio.h> 2 #include <vector> 3 #define N 10010 4 5 using namespace std; 6 7 vector<int> a[N]; 8 int mark[N], dp[N][3]; 9 const int inf = 12345678; 10 11 int min(int x, int y) 12 { 13 return x<y? x: y; 14 } 15 16 int limit_inf(int x) 17 { 18 return x>inf? inf: x; 19 } 20 21 int f(int x, vector<int> b) 22 { 23 int i, j, k, sum1, min1; 24 25 //leaf 26 if(b.size() == 0) 27 { 28 dp[x][0] = 0; 29 dp[x][1] = inf; 30 dp[x][2] = 1; 31 return 0; 32 } 33 34 //0 35 sum1 = 0; 36 for(i=0; i<b.size(); i++) 37 { 38 sum1 += dp[b[i]][1]; 39 } 40 dp[x][0] = limit_inf(sum1); 41 42 //1 43 min1 = inf; 44 for(i=0; i<b.size(); i++) 45 { 46 sum1 = dp[b[i]][2]; 47 for(j=0; j<b.size(); j++) 48 { 49 if(j != i) 50 { 51 sum1 += min(dp[b[j]][1], dp[b[j]][2]); 52 } 53 } 54 min1 = min(min1, sum1); 55 } 56 dp[x][1] = limit_inf(min1); 57 58 //2 59 sum1 = 0; 60 for(i=0; i<b.size(); i++) 61 { 62 sum1 += min(dp[b[i]][0], min(dp[b[i]][1], dp[b[i]][2])); 63 } 64 sum1 += 1; 65 dp[x][2] = limit_inf(sum1); 66 return 0; 67 } 68 69 int dfs(int x) 70 { 71 int i, j; 72 vector<int> b; 73 b.clear(); 74 //printf("(%d: ", x); 75 for(i=0; i<a[x].size(); i++) 76 { 77 j = a[x][i]; 78 if(mark[j] == 0) 79 { 80 b.push_back(j); 81 mark[j] = 1; 82 dfs(j); 83 } 84 } 85 f(x, b); 86 //printf("[%d,%d,%d]", dp[x][0], dp[x][1], dp[x][2]); 87 //printf(" ) "); 88 return 0; 89 } 90 91 int main() 92 { 93 int n, i, x, y; 94 while(~scanf("%d", &n)) 95 { 96 for(i=1; i<=n; i++) 97 { 98 //dp[i][0] = dp[i][1] = dp[1][2] = inf; 99 mark[i] = 0; 100 a[i].clear(); 101 } 102 for(i=1; i<=n-1; i++) 103 { 104 scanf("%d%d", &x, &y); 105 a[x].push_back(y); 106 a[y].push_back(x); 107 } 108 mark[1] = 1; 109 dfs(1); 110 printf("%d\n", min(dp[1][1], dp[1][2])); 111 if(dp[1][2] == inf) 112 { 113 dp[1][2] = -1; 114 } 115 //printf("\n"); 116 //for(i=1; i<=n; i++) 117 //{ 118 // printf("%5d %5d %5d\n", dp[i][0], dp[i][1], dp[i][2]); 119 //} 120 } 121 return 0; 122 }