Debug
Time Limit:1000MS Memory Limit:65536K
Description
经过了一整夜的激战,rc的部队终于攻下了虫族的首都Bugzilla。现在,rc决定亲自带领一队突击队员在虫族庞大的地道中寻找他的宿命之敌—Bug。
Bugzilla由N个基地组成。这N个基地被N-1段双向地道连接在一起,每段地道都连接两个基地,并且保证任意两个基地之间都可以通过地道互相到达。Bug就藏在其中的某段地道中。
开始时rc可以乘坐运输机降落在任何一个基地。每次到达一个基地时,rc都可以选择呼叫运输机将他和他的部队运输到任意另一个基地,或者进入与这个基地相邻的一段地道进行搜索。但为了防止Bug跑进已经搜索过的地道,他在离开一个基地进入地道或登上运输机时一定会将这个基地炸毁。基地一旦被炸毁就不再和与它相邻的地道连接。但这样一来,如果进入的地道另一端的基地已经在之前被炸毁,rc和他的部下就将被永远困在地道中。因为地道生活并不有趣,所以在这种情况下rc是不会进入这段地道的。
不过,这也带来了一个问题,就是rc也许不能搜索所有的地道了。现在rc想知道的是他最多能搜索多少段地道。作为有幸被留在运输机上看风景而不必冒着成为虫食的危险钻入地下的人,你必须完成这个任务!
Input
第一行一个整数N(2<=N<=100000),表示基地的个数。基地被编号为1~N的整数。
以下N-1行,每行两个整数A和B,表示编号为A的基地和编号为B的基地间有一段地道。
Output
一个整数,表示RC最多能搜索的地道的数目
Sample Input
6
1 2
3 2
2 4
4 5
4 6
Sample Output
4
分析:
开始的剩的边数为
n
−
1
n-1
n−1…
如果有点
i
i
i的度数>
2
2
2 我们就要删除 连接
t
a
ta
ta父节点的边
有
>
1
>1
>1个叶节点时 搜子节点 一定比搜父节点更优
如果选父节点
j
j
j 将放弃与
j
j
j相连的所有点 这样就不符合最优解了
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
using namespace std;
int tot,n,x,y,head[N],e[N],SCP[N],ans;
struct node{
int to,next;
}a[N*2];
void add(int x,int y)
{
a[++tot]=(node){y,head[x]}; //邻接表
head[x]=tot;
}
void dfs(int dep,int ftr) //搜索
{
e[dep]=1;
if(SCP[dep]==1&&a[head[dep]].to==ftr) //当前为叶节点并只有一个父节点
return;
for(int i=head[dep];i;i=a[i].next)
{
if(e[a[i].to]==1) continue; //不重复走
dfs(a[i].to,dep); //继续搜
}
if(SCP[dep]>2) //度数>2
{
ans=ans-(SCP[dep]-2); //删边
SCP[ftr]--; //父节点度-1
}
}
int main(){
scanf("%d",&n);
ans=n-1;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
SCP[x]++;
SCP[y]++; //记录度数
}
dfs(1,0);
printf("%d",ans);
return 0;
}