POJ-3107-Godfather

来源:互联网 发布:地球为什么会自转 知乎 编辑:程序博客网 时间:2024/05/16 19:12

Godfather
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 7885 Accepted: 2786

Description

Last years Chicago was full of gangster fights and strange murders. The chief of the police got really tired of all these crimes, and decided to arrest the mafia leaders.

Unfortunately, the structure of Chicago mafia is rather complicated. There aren persons known to be related to mafia. The police have traced their activity for some time, and know that some of them are communicating with each other. Based on the data collected, the chief of the police suggests that the mafia hierarchy can be represented as a tree. The head of the mafia, Godfather, is the root of the tree, and if some person is represented by a node in the tree, its direct subordinates are represented by the children of that node. For the purpose of conspiracy the gangsters only communicate with their direct subordinates and their direct master.

Unfortunately, though the police know gangsters’ communications, they do not know who is a master in any pair of communicating persons. Thus they only have an undirected tree of communications, and do not know who Godfather is.

Based on the idea that Godfather wants to have the most possible control over mafia, the chief of the police has made a suggestion that Godfather is such a person that after deleting it from the communications tree the size of the largest remaining connected component is as small as possible. Help the police to find all potential Godfathers and they will arrest them.

Input

The first line of the input file contains n — the number of persons suspected to belong to mafia (2 ≤n ≤ 50 000). Let them be numbered from 1 ton.

The following n − 1 lines contain two integer numbers each. The pair ai, bi means that the gangsterai has communicated with the gangsterbi. It is guaranteed that the gangsters’ communications form a tree.

Output

Print the numbers of all persons that are suspected to be Godfather. The numbers must be printed in the increasing order, separated by spaces.

Sample Input

61 22 32 53 43 6

Sample Output

2 3

Source

Northeastern Europe 2005, Northern Subregion

题意:警察要抓黑手党的教父,然后不知道是谁,只知道有n个人,以及谁与谁联系,而黑手党内为了阴谋交流都只是上下级之间单一交流,因为不知道教父是谁,所以就要抓最大概率的那个人,警察局长规定,如果去掉教父,而剩下的能够联系的人,所能形成的最多人的网络人最少。也就是树中去除一个点,形成的子树中点最多的子树中节点要尽量少。

当时读题意,看了半天又教父,黑手党又警察的,就倒数第二句有用呐,就读那一句就能明白什么意思了,前面的句子就是废话。。。

按照题意,去点,用个数组存下删点后得到的最大子树点数值,然后循环下输出和最小值相等的点就行了。

代码:

#include<iostream>#include<string.h>#include<math.h>#include<stdio.h>using namespace std;int p;int head[100005];struct f{int now,next;}tree[100005];int bj[50005],s[50005];void build(int a,int b){tree[p].now=b;tree[p].next=head[a];head[a]=p;p++;}void dfs(int a,int b){int nnext;for(int i=head[a];i!=-1;i=tree[i].next)    {    nnext=tree[i].now;    if(nnext!=b)        {        dfs(nnext,a);        bj[a]+=bj[nnext];        }    }}void dfs2(int a,int b){int nnext;for(int i=head[a];i!=-1;i=tree[i].next)    {    nnext=tree[i].now;    s[a]=max(bj[nnext],s[a]);    if(nnext!=b)        {        int x=bj[a];        int y=bj[nnext];        bj[a]=x-y;        bj[nnext]=x;        dfs2(nnext,a);        bj[a]=x;        bj[nnext]=y;        }    }}int main(){int n,a,b;while(cin>>n)    {    memset(head,-1,sizeof(head));    p=0;    for(int i=1;i<n;i++)        {        scanf("%d%d",&a,&b);        build(a,b);        build(b,a);        bj[i]=1;        }    bj[n]=1;    dfs(1,-1);    dfs2(1,-1);    int ans=999999999;    for(int i=1;i<=n;i++)        ans=min(ans,s[i]);    for(int i=1;i<=n;i++)        if(ans==s[i])            cout<<i<<" ";    cout<<endl;    }return 0;}




原创粉丝点击