题意:给定一棵无根树,删除树中一个节点,使得剩下各子树的包含的节点数最大值最小,问树中有多少个这样的节点? 然后字典序输出。
解题:遍历一遍所有节点就可以了。很简单,但是TLE了一上午,原因就是数据很变态吧,卡STL(可能是自己用的不熟练吧),然后自己写一个就直接AC了。
代码如下:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 50001
#define Max (1<<(31)-1)
struct Node{
int v,next;
}arcnode[N*2];
int vnode[N],v_dp[N],ans[N];
int ans_num,ans_key,k,num;
bool vist[N];
void Addedge(int u,int v)
{
arcnode[k].v=v;
arcnode[k].next=vnode[u];
vnode[u]=k++;
}
void dfs(int key)
{
vist[key]=false;
v_dp[key]=1;
int i,v,maxx=-1;
for(i=vnode[key];i;i=arcnode[i].next)
{
v=arcnode[i].v;
if(!vist[v]) continue;
dfs(v);
v_dp[key]+=v_dp[v];
maxx=max(maxx,v_dp[v]);
}
maxx=max(maxx,num-v_dp[key]);
if(maxx==ans_key)
ans[ans_num++]=key;
if(maxx<ans_key)
{
ans_num=0;
ans[ans_num++]=key;
ans_key=maxx;
}
}
int main()
{
while(~scanf("%d",&num))
{
int i,a,b;
k=1;ans_num=0;ans_key=num;
memset(vist,true,sizeof(vist));
memset(vnode,0,sizeof(vnode));
for(i=1;i<num;i++)
{
scanf("%d%d",&a,&b);
Addedge(a,b); Addedge(b,a);
}
dfs(1);
sort(ans,ans+ans_num);
for(i=0;i<ans_num;i++)
{
printf("%d",ans[i]);
if(i!=ans_num-1) putchar(' ');
else puts("");
}
}
}