解题思路:
将一棵树变成一个环,如果一个结点的分叉数目大于等于2,则将它与父节点断开,并且断开子结点数目sum - 2条边,并再次连接sum-2个儿子形成一条直链然后这条游离链与另一条游离链相连,共需要2*(sum-1)个操作,如果该结点为根结点,则一共需要2 * (sum - 2)种操作。
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <queue> #include <stack> #pragma comment(linker,"/STACK:102400000,102400000") #define LL long long using namespace std; const int MAXN = 1000000 + 10; int ans; vector<int>G[MAXN]; int n; int dfs(int u, int pre) { int sz = G[u].size(); int sum = 0; for(int i=0;i<sz;i++) { int v = G[u][i]; if(v == pre) continue; sum += dfs(v, u); } if(sum >= 2) { if(u == 1) ans += 2 * (sum - 2); else ans += 2 * (sum - 1); return 0; } return 1; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i=0;i<=n;i++) G[i].clear(); ans = 0; int u, v; for(int i=1;i<n;i++) { scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } dfs(1, -1); printf("%d\n", ans + 1); } return 0; }
原文地址:http://blog.csdn.net/moguxiaozhe/article/details/44452003