poj 2378
题目大意:给定一棵树的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; }