poj 3107 Godfather (树形dp)

Godfather

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5064   Accepted: 1769

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 are n 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 to n.

The following n ? 1 lines contain two integer numbers each. The pair aibi means that the gangster ai has communicated with the gangster bi. 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

6
1 2
2 3
2 5
3 4
3 6

Sample Output

2 3

进行深搜,找到每个节点的子节点构成子树的节点数目,那么,判断更新最小子树或者进入一个新的mafia leaders。

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define ll long long
#define N 51000
#define mem(a,t) memset(a,t,sizeof(a))
vector<int>g[N];
int ans[N];

struct ege
{
    int v,next;
}e[N*2];
int head[N];
int cnt,n,n1,mmin;
int num[N];             //记录i子树包含节点数
void add(int u,int v)
{
    e[cnt].v=v;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
int dfs(int u,int fa)
{
    int i,v,tmp=0,t1;
    num[u]=1;              //求当前树枝U的子节点以及本身的个数和
    for(i=head[u];i!=-1;i=e[i].next)
    {
        v=e[i].v;
        if(v!=fa)
        {
            num[u]+=dfs(v,u);
            tmp=max(tmp,num[v]);
        }
    }
    t1=max(tmp,n-num[u]); //去掉点u后,最大树的节点数目
    if(t1<mmin)
    {
        mmin=t1;
        n1=0;
        ans[n1++]=u;
    }
    else if(t1==mmin)
    {
        ans[n1++]=u;
    }
    return num[u];
}

int main()
{
    //freopen("in.txt","r",stdin);
    int i,j,u,v;
    while(~scanf("%d",&n))
    {
        mem(head,-1);
        cnt=0;
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        mem(num,0);     //num[i]记录节点i的子树点个数
        n1=0;
        mmin=n;
        dfs(1,-1);
        sort(ans,ans+n1);
        for(i=0;i<n1;i++)
            printf("%d%c",ans[i],(i==n1-1)?'\n':' ');
    }
    return 0;
}
时间: 2024-08-25 17:38:08

poj 3107 Godfather (树形dp)的相关文章

poj 3107 Godfather 求树的重心【树形dp】

poj 3107 Godfather 和poj 1655差不多,那道会了这个也就差不多了. 题意:从小到大输出树的重心. 题会卡stl,要用邻接表存树..... 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn = 50006; 7 const int INF = 1

POJ 2342 (树形DP)

Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3863   Accepted: 2172 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure

POJ 1849 Two (树形dp 树的直径 两种方法)

Two Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1232   Accepted: 619 Description The city consists of intersections and streets that connect them. Heavy snow covered the city so the mayor Milan gave to the winter-service a list of st

[POJ 1155] TELE (树形dp)

题目链接:http://poj.org/problem?id=1155 题目大意:电视台要广播电视节目,要经过中转机构,到观众.从电视台到中转商到观众是一个树形结构,经过一条边需要支付成本.现在给你每两个节点之间传播的成本,给你每个观众会付的钱,问你电视台在不亏本的情况下最多能给多少个观众看节目. 这是我的第一道树形dp..无耻的看了题解.. 设计状态:dp[u][i]代表以u为根的子树中有i个观众,能够得到的最大收入. 状态转移:dp[u][i] = max(dp[u][i],dp[u][i-

poj 1947 经典树形dp

经典树形dp:问在一棵树上最少删除多少条边可以分离出一个节点数为p的子树. 定义状态: dp[i][j]表示从i为根的子树上分离出一个节点数为j的子树的代价(最少需要删除的边数). 考虑i节点的每个儿子ii,ii可以选或者不选(切断),然后就转化成了背包问题. dp[u][j] = min( dp[u][j], dp[u][j - k] + dp[v][k] ); 1 #include <iostream> 2 #include <cstring> 3 #include <c

POJ Anniversary party 树形DP

/* 树形dp: 给一颗树,要求一组节点,节点之间没有父子关系,并且使得所有的节点的权值和最大 对于每一个节点,我们有两种状态 dp[i][0]表示不选择节点i,以节点i为根的子树所能形成的节点集所能获得的最大权值和 dp[i][1]表示选择节点i ,同上! 转移方程: dp[i][0]+=max(dp[i_son][1],dp[i_son][0])如果没选择的话,那么子树可选择可不选择 dp[i][1]+=dp[i_son][0] 选择了之后,子树只能不选择 最后输出max(dp[i][0],

POJ 3107 Godfather (树的重心)

题目地址:POJ 3107 还是裸的树的重心,只不过这个要求将所有的重心都输出.很简单. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include &

POJ 2486-Apple Tree(树形DP)(难)

题意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 思路:(思路转自http://blog.csdn.net/libin56842/article/details/10101807) 树形dp,比较经典的一个树形dp.首先很容易就可以想到用dp[root][k]表示以root为根的子树中最多走k时所能获得的最多苹果数,接下去我们很习惯地会想到将k步在root的所有子结点中分配,也就是进行一次背包,就可以得出此时状态的最优解了,但是这里还有一个问

POJ 3107 Godfather (树形dp)

题目链接 虽然题目不难,但是1A还是很爽, 只是刚开始理解错题意了,想了好久. 还有据说这个题用vector会超时,看了以后还是用邻接吧. 题意: 给一颗树,保证是一颗树,求去掉一个点以后的联通块里节点的数目的 最大值最小,求这样的点,并按照递增顺序输出. 分析: d[father] = max(n-sum, d[son]);   sum代表这个节点以下的全部节点总数, 去掉一个节点的联通块的最大的节点数 等于 整个树里的节点数减去这个节点下的总数 和 子树的数目的 最大值. 1 #includ