题目大意:给定一棵树的n个节点和n-1条边,对于每个节点,要求去掉它之后所有子树的最大节点数,并输出最大节点数小于n/2的节点编号
简单题。两次dfs即可。
#include<iostream>
#include<fstream>
using namespace std;
typedef struct e{
int data;
e* next;
}e;
int n;
e edge[10001];
int d[10001];
int v[10001];
int dp[10001];
int solve(int s){
d[s]=1;
v[s]=1;
e *p=edge[s].next;
while(p){
if(!v[p->data])
d[s]+=solve(p->data);
p=p->next;
}
return d[s];
}
void solve2(int s){
v[s]=0;
e *p=edge[s].next;
int t=0;
while(p){
if(v[p->data])
{
solve2(p->data);
t=max(t,d[p->data]);
}
else
t=max(t,n-d[s]);
p=p->next;
}
dp[s]=t;
}
void read(){
// ifstream cin("in.txt");
int i,j,k;
cin>>n;
for(i=1;i<=n;i++)
{
edge[i].data=i;
edge[i].next=0;
}
while(cin>>i>>j)
{
e *p=new e;
p->data=i;
p->next=edge[j].next;
edge[j].next=p;
e *q=new e;
q->data=j;
q->next=edge[i].next;
edge[i].next=q;
}
solve(1);
solve2(1);
for(i=1;i<=n;i++)
if(dp[i]<=n/2)
cout<<i<<endl;
}
int main(){
read();
return 0;
}