ydc题解上写着贪心,后来又说是树形dp。。。可惜看不懂(顺便骗三连)
其实就是每个叶子开始拉一条链,从下面一路走上来,遇到能把两条链合起来的就合起来就好了。
1 /************************************************************** 2 Problem: 1907 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:112 ms 7 Memory:1396 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 13 using namespace std; 14 const int N = 1e4 + 5; 15 16 struct edge { 17 int next, to; 18 edge() {} 19 edge(int _n, int _t) : next(_n), to(_t) {} 20 } e[N << 1]; 21 22 struct tree_node { 23 int fa, ans, used; 24 } tr[N]; 25 26 int n; 27 int first[N], tot; 28 29 inline int read() { 30 int x = 0; 31 char ch = getchar(); 32 while (ch < '0' || '9' < ch) 33 ch = getchar(); 34 while ('0' <= ch && ch <= '9') { 35 x = x * 10 + ch - '0'; 36 ch = getchar(); 37 } 38 return x; 39 } 40 41 void Add_Edges(int x, int y) { 42 e[++tot] = edge(first[x], y), first[x] = tot; 43 e[++tot] = edge(first[y], x), first[y] = tot; 44 } 45 46 #define y e[x].to 47 int dfs(int p) { 48 int x, cnt = 0; 49 tr[p].ans = 1, tr[p].used = 0; 50 for (x = first[p]; x; x = e[x].next) 51 if (y != tr[p].fa) { 52 tr[y].fa = p; 53 dfs(y); 54 tr[p].ans += tr[y].ans; 55 if (!tr[y].used) ++cnt; 56 } 57 if (cnt >= 2) tr[p].ans -= 2, tr[p].used = 1; 58 else if (cnt == 1) --tr[p].ans; 59 } 60 #undef y 61 62 int main() { 63 int i, T; 64 T = read(); 65 while (T--) { 66 n = read(), tot = 0; 67 memset(first, 0, sizeof(first)); 68 for (i = 1; i < n; ++i) 69 Add_Edges(read(), read()); 70 dfs(1); 71 printf("%d\n", tr[1].ans); 72 } 73 return 0; 74 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen