D. 爱好和平 2014新生暑假个人排位赛06
时间限制 1000 ms
内存限制65536 KB
题目描述
在星际时代,每个帝国都靠着贸易路线连接着各个联盟星球,这些贸易路线都是双向可达的。一个帝国的综合实力由他贸易连接着的联盟星球数决定。
学姐作为Mays帝国的领袖,长期与Luke帝国保持着敌对关系,爱好和平的学姐希望结束长达几个世纪的战争,于是找实验室定做了一颗代号小苹果的炸弹,可以定点摧毁一颗星球,这颗星球被毁后,与它相连的全部贸易就都被切断了,这样Luke帝国可能就被切断为一个小联盟,他们就再也不会对学姐的地位构成威胁啦~
经过调查,Luke帝国为了节约经费,他的联盟星之间都有且仅有一条直接或间接的贸易通路。
现在给出Luke帝国的贸易线路,学姐想知道摧毁哪一颗行星可以使得分裂后的若干Luke联盟威胁最大的分部最小。
输入格式
输入有多组数据,组数不大于10组。每一组开头一行为n,m,表示Luke帝国的联盟星球数量,和贸易关系数,接下来m行,每行两个整数u,v,表示星球u,v之间存在直接的贸易路线,1<=u,v<=n,1<=n,m<=100000
输出格式
输出一个数表示推荐学姐摧毁的星球,如果有多解,输出编号最小的一个。
输入样例
5 4
1 2
1 3
1 4
4 5
输出样例
1
思路:因为经过调查,Luke帝国为了节约经费,他的联盟星之间都有且仅有一条直接或间接的贸易通路。所以可以看成一个树。对于树中的每个节点,记录下它子节点的连通块中节点个数,然后往上的时候就累加,则父节点联通块个数就是总数减子节点联通块个数的总和。然后一遍dfs即可。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#define maxn 100005
//#define LOCAL
using namespace std;
vector<int> G[maxn];
int sv[maxn],fv[maxn],vis[maxn],connected[maxn];
int n,m,deep;
template<class T>
inline bool read(T &n)
{
T signal = 1,x =0;
char ch =getchar();
while((ch < '0' || ch >'9') && ch != EOF && ch != '-')
ch = getchar();
if(ch == EOF) return false;
if(ch == '-') ch = getchar(),signal = -1;
while(ch>='0' && ch <= '9'){
x *= 10;
x += ch -'0';
ch = getchar();
}
n = signal * x;
return true;
}
void dfs(int u,int f)
{
vis[u]=1;
//printf("u=%d f=%d\n",u,f);system("pause");
int cnt=0;
connected[u]=1;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(v!=f&&!vis[v])
{
cnt++;
dfs(v,u);//if(u==4)printf("connect[%d]=%d\n",v,connected[v]);
sv[u]=max(sv[u],connected[v]);
connected[u]+=connected[v];
}
}
if(cnt==0){sv[u]=0;connected[u]=1;}
//cout<<cnt<<endl;
//value1[u]=n-1;
}
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif // LOCAL
while(scanf("%d%d",&n,&m)==2)
{
//cout<<n<<' '<<m<<endl;
for(int i=1;i<=n;i++)G[i].clear();
memset(sv,0,sizeof(sv));
memset(fv,0,sizeof(fv));
//memset(connected,0,sizeof(connected));
for(int i=1;i<=m;i++)
{
int a,b;
read(a);read(b);
G[a].push_back(b);
G[b].push_back(a);
}
memset(vis,0,sizeof(vis));
dfs(1,-1);
//memset(vis,0,sizeof(vis));
//for(int i=1;i<=n;i++)printf("value[%d]=%d\n",i,sv[i]);
//dfs2(1,-1);
//cout<<value[1]<<endl;
//for(int i=1;i<=n;i++)printf("value[%d]=%d\n",i,fv[i]);
//for(int i=1;i<=n;i++)printf("value[%d]=%d\n",i,max(n-connected[i],sv[i]));
int ans=0x7fffffff,maxx;
for(int i=1;i<=n;i++)if(max(n-connected[i],sv[i])<ans){ans=max(n-connected[i],sv[i]);maxx=i;}
printf("%d\n",maxx);
}
return 0;
}