A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 unit of cost respectively. The nodes are labeled from 1 to N. Your job is to transform the tree to a cycle(without superfluous edges) using minimal cost.
A cycle of n nodes is defined as follows: (1)a graph with n nodes and n edges (2)the degree of every node is 2 (3) each node can reach every other node with these N edges.
A cycle of n nodes is defined as follows: (1)a graph with n nodes and n edges (2)the degree of every node is 2 (3) each node can reach every other node with these N edges.
InputThe first line contains the number of test cases T( T<=10 ). Following lines are the scenarios of each test case.
In the first line of each test case, there is a single integer N( 3<=N<=1000000 ) - the number of nodes in the tree. The following N-1 lines describe the N-1 edges of the tree. Each line has a pair of integer U, V ( 1<=U,V<=N ), describing a bidirectional edge (U, V).
OutputFor each test case, please output one integer representing minimal cost to transform the tree to a cycle.
Sample Input
1 4 1 2 2 3 2 4Sample Output
3Hint
In the sample above, you can disconnect (2,4) and then connect (1, 4) and (3, 4), and the total cost is 3.
题意 : 给你一颗树,要求将此树变成一个环,并且要求每个点的度为2,删去或增加一条边的花费都是1,求最小的花费。
思路分析:思维题,对于树上的点如果其不是根节点并且具有3个分支,则其一定要去掉一个,保留两个,然后其在返回父节点的时候它是不给父节点在提供任何分支的,否则会提供一个分支。
代码示例:
const int maxn = 1e6+5; int n; vector<int>ve[maxn]; int ans; int dfs(int x, int fa){ int sum = 0; for(int i = 0; i < ve[x].size(); i++){ int to = ve[x][i]; if (to == fa) continue; sum += dfs(to, x); } if (x != 1 && sum >= 2){ ans += sum-1; return 0; } else if (x == 1 && sum > 2){ ans += sum-2; } return 1; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int t; int x, y; cin >> t; while(t--){ scanf("%d", &n); for(int i = 1; i <= n; i++) ve[i].clear(); for(int i = 1; i < n; i++){ scanf("%d%d", &x, &y); ve[x].push_back(y); ve[y].push_back(x); } ans = 0; dfs(1, 0); printf("%d ", ans*2+1); } return 0; }