给一棵树,每次操作可以删一条边或者加一条边,目标是变成一个环。
果然是最近智商君下线了...写了一下午的树DP,知道哪有问题就是改不过来...后来发现只要从根遍历一遍就行..对每个节点,如果有两个及以上的孩子,就删掉多余的保留两个分支并且删掉与父节点连接的边,否则不用管。。因为没删一条边都要加回来,最后还需要一条边连接头尾,所以答案就是删除的边的数量*2+1 ....
/*=============================================================================
# Author:Erich
# FileName:
=============================================================================*/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#define lson id<<1,l,m
#define rson id<<1|1,m+1,r
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=1ll<<60;
const double PI=acos(-1.0);
int n,m;
const int maxn=1000050;
vector<int> g[maxn];
int ans;
int dfs(int u,int fa)
{
int v;
int cnt=0;
for (int i=0; i<g[u].size(); i++)
{
v=g[u][i];
if (v==fa) continue;
cnt+=dfs(v,u);
}
if (cnt>=2)
{
if (u==1) ans+=cnt-2;
else ans+=cnt-1;
return 0;
}
return 1;
}
int main()
{
//freopen("in.txt","r",stdin);
int tt,x,y;
scanf("%d",&tt);
while(tt--)
{
scanf("%d",&n);
for (int i=0; i<=n; i++) g[i].clear();
for (int i=1; i<n; i++)
{
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
ans=0;
dfs(1,-1);
cout<<ans*2+1<<endl;
}
return 0;
}