愿大地母亲保佑你
题目描述
牛头人们的生活从来不是和平的。
刺背野猪人、鹰身人等种族经常来骚扰他们,还有一个很欠抽的某巨魔及其麾下的军队。
某天,仍然是在彰异牛的注视下,某牛头人临危受命,在大地母亲的保佑下,拿回了一张图纸,图纸上画的是某巨魔的组织关系示意图。
这个图中包含的是某巨魔组织的从属关系(直属上级和直属下级),图绘制出来后的形态是
N
个点的树,但是这张图没有告诉牛头人对于一对有从属关系的巨魔,谁是上级谁是下级。
巨魔中肯定有个最高指挥官(即没有从属上级的巨魔),但是牛头人现在不好判断哪个巨魔是最高指挥官了。
经过一个牛头人大德鲁伊分析后,得出结论,如果将某个巨魔从这个关系图中去掉后,这个图剩下的连通块中,点数最多那个块在所有去掉的方案中的点数最少,那么这个巨魔可能就是最高指挥官。
现在,牛头人需要你找出一个最高指挥官。
输入格式
第一行
接下来
输出格式
输出一个数字,即巨魔最高指挥官的编号。
如果有多个输出编号最小的那个。
样例输入
3
1 2
2 3
样例输出
2
样例解释
1
在图中去掉后,剩下的连通块点数最多的为
2
在图中去掉后,剩下的连通块点数最多的为
数据范围
20%
的数据
1≤N≤1000
。
100%
的数据
1≤N≤106
。
Solution
首先无向图转有向图;
当一个点被删掉之后,产生的连通块有:
一:此点上方的所有点。
二:以此点的每一个儿子为根的子树。
然后就可以愉快的打擂台了。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#define Max(x,y) ((x)>(y)?(x):(y))
using namespace std;
int n,cnt;
int head[1000010],nxt[2000010],data[2000010],f[2000010],maxn=0x3f3f3f3f,maxt;
void add(int x,int y){
nxt[cnt]=head[x];data[cnt]=y;head[x]=cnt++;
nxt[cnt]=head[y];data[cnt]=x;head[y]=cnt++;
}
void dfs(int now,int pre){
f[now]=1;
int Maxn=-1;
for(int i=head[now];i!=-1;i=nxt[i])if(data[i]!=pre){
dfs(data[i],now);
f[now]+=f[data[i]];
Maxn=Max(Maxn,f[data[i]]);
}
Maxn=Max(Maxn,n-f[now]);
if(maxn>Maxn){
maxn=Maxn;
maxt=now;
}
}
int main(){
freopen("bless.in","r",stdin);
freopen("bless.out","w",stdout);
memset(head,-1,sizeof head);
scanf("%d",&n);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
dfs(1,0);
printf("%d\n",maxt);
return 0;
}