您的位置:首页 > 其它

POJ 2378 Tree Cutting (树的重心,微变形)

2015-09-25 10:29 453 查看
题意:

  给定一棵树,n个节点,若删除点v使得剩下的连通快最大都不超过n/2,则称这样的点满足要求。求所有这样的点,若没有这样的点,输出NONE。

思路:

  只需要拿“求树的重心”的代码改一行就OK了。因为依然是在判别最大连通块的点数。

//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <deque>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define INF 0x7f7f7f7f
#define LL  long long
using namespace std;
const double PI  = acos(-1.0);
const int N=10010;
int n,  edge_cnt, head
;

struct node
{
int from, to, next;
node(){};
node(int from,int to,int next):from(from),to(to),next(next){};
}edge[N*2];

void add_node(int from,int to)
{
edge[edge_cnt]=node(from,to,head[from]);
head[from]=edge_cnt++;
}
deque<int> que;

int DFS(int t,int far)
{
node e;
int big=0, sum=0;
for(int i=head[t]; i!=-1; i=e.next)
{
e=edge[i];
if(e.to==far)   continue;

int tmp=DFS(e.to, t);
big=max(big, tmp);
sum+=tmp;
}
big=max(big, n-sum-1);

if(big<=n/2)    que.push_back(t);//只改这处地方
return sum+1;
}

int main()
{
//freopen("input.txt", "r", stdin);
int a, b;
while(~scanf("%d",&n))
{
edge_cnt=0;
memset(head,-1,sizeof(head));

for(int i=1; i<n; i++)
{
scanf("%d%d",&a,&b);
add_node(a,b);
add_node(b,a);
}
DFS(1,-1);
sort(que.begin(),que.end());
if(que.empty()) puts("NONE");
else
{
while(!que.empty())
{
printf("%d\n",que.front());
que.pop_front();
}
}
}
return 0;
}


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