您的位置:首页 > 编程语言 > Go语言

POJ 3107 - Godfather

2012-09-05 12:20 225 查看
题目地址: http://poj.org/problem?id=3107

DFS遍历。

利用树化区间的思想。

能想到这个方法,就很好做了。

枚举每一个节点为断点:

1. 那么其每【一个子节点】=【一颗单独的树】。

2. 而【整棵树】减去【以这个节点为根的树】=【单独一棵树】。

#include<iostream>
#include<cstdio>
#include<cstring>
#define bug puts("here");

using namespace std;

struct Edge{
int gt,nx;
}edge[110000];
int ef[51000],tol;

void add_edge(int a,int b){
edge[tol].gt=b;
edge[tol].nx=ef[a];
ef[a]=tol++;
}

int has[51000];
int lft[51000],rit[51000];
int now;
int father[51000];

void dfs(int x){
int k;
lft[x]=++now;
has[x]=1;
for(k=ef[x];k!=-1;k=edge[k].nx){
if(has[edge[k].gt]) continue;
dfs(edge[k].gt);
father[edge[k].gt]=x;
}
rit[x]=now;
}

int res[51000],cnt;

int getlen(int x){
return rit[x]-lft[x]+1;
}

int main(){
int n,i,a,b,k,mn,tmp;
scanf("%d",&n);
memset(ef,-1,sizeof(ef));
tol=0;
for(i=1;i<n;i++){
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
now=0;
dfs(1);
father[1]=-1;
for(i=1;i<=n;i++){
if(father[i]==-1){
mn=100000;
tmp=0;
}
else{
tmp=getlen(1)-getlen(i);
}
for(k=ef[i];k!=-1;k=edge[k].nx){
if(father[i]==edge[k].gt) continue;
if(tmp<getlen(edge[k].gt))
tmp=getlen(edge[k].gt);
}
if(tmp<mn){
cnt=0;
mn=tmp;
res[cnt++]=i;
}
else if(tmp==mn){
res[cnt++]=i;
}
}
printf("%d",res[0]);
for(i=1;i<cnt;i++)
printf(" %d",res[i]);
puts("");
return 0;
}
/*
7
1 2
2 5
2 3
3 4
3 6
6 7

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: