poj2378

版权声明:转就转吧~~记得声明噢~~ https://blog.csdn.net/Soul_97/article/details/83818492

http://poj.org/problem?id=2378

这题大概算是求树的重心的改编版,求一个点,把这个点删去之后它的所有子数的最大节点数小于总节点数的一半即满足要求

相对于POJ3107来说还简化了一些,

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 1e4 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int vis[N],sum[N],ans[N],head[N];
int n,top,cnt,min_node;
struct edge{
    int v,next;
}e[2*N];
void addEdge(int a,int b)
{
    e[top].v = b;
    e[top].next = head[a];
    head[a] = top++;
}
void dfs(int k)
{
    int res = -1;
    sum[k] = 1;
    vis[k] = 1;
    for(int i = head[k];i;i = e[i].next){
        int tmp = e[i].v;
        if(vis[tmp]) continue;
        dfs(tmp);
        sum[k] += sum[tmp];
        res = max(res,sum[tmp]);
    }
    res = max(res,n-sum[k]);
    if(res <= n/2){
        ans[cnt++] = k;
    }
}
int main()
{
    top = 1;
    scanf("%d",&n);
    for(int i = 1;i < n;i ++){
        int x,y;
        scanf("%d%d",&x,&y);
        addEdge(x,y);
        addEdge(y,x);
    }
    dfs(1);
    if(!cnt)
        cout << "NONE" << endl;
    else{
        sort(ans,ans+cnt);
        for(int i = 0;i < cnt;i ++)
            cout << ans[i] << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Soul_97/article/details/83818492