hdu4714
题目
给你一棵树,删去或者添加一条边花费的代价都是1,问最小的花费是多少使得经过删边加边后树变成一个环。
思路
还是云里雾里的,只知道最终每个节点的度数是2,那么当它的分支大于等于2的时候一定要删边,有删边就一定有对应的增边,对于根节点,我们要保留两个度,所以是son-2(son是子节点个数),其他的在保留2的同时要把对父的删去,是son-2+1,最后除了son*2之外,还要加一条边,所以加一。
代码
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<stack>
using namespace std;
typedef long long ll;
const int maxn=1000100;
int head[maxn],tot,ans;
struct node
{
int next;
int to;
} edge[maxn*2];
void addedge(int from,int to)
{
edge[tot].to=to;
edge[tot].next=head[from];
head[from]=tot++;
}
int dfs(int u,int fa)
{
int num=0;
for(int i=head[u]; ~i; i=edge[i].next)
{
int v=edge[i].to;
if(v==fa) continue;
num+=dfs(v,u);
}
if(num>1)
{
if(fa==-1) ans+=num-2;
else ans+=num-1;
return 0;
}
return 1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
memset(head,-1,sizeof(head));
tot=0;
scanf("%d",&n);
for(int i=0; i<n-1; i++)
{
int a,b;
scanf("%d %d",&a,&b);
addedge(a,b);
addedge(b,a);
}
ans=0;
dfs(1,-1);
printf("%d\n",ans+ans+1);
}
return 0;
}