POJ 3107 Godfather树形dfs
http://poj.org/problem?id=3107
题意:给出n个点,n-1条边,去掉一个点(x)后形成的子树最多点 最小的点(x)
以前貌似做过,现在重新用树形dfs缕缕思路
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #define Max(a,b)a>b?a:b #define Min(a,b)a<b?a:b #define MAX 50005 using namespace std; int head[MAX],mark[MAX],vs[MAX],sumVal[MAX],maxSub[MAX]; int n,s_edge,cnt,MIN; struct Edge { int to,nxt; }edge[MAX*2]; void addedge(int u,int v) { s_edge++; edge[s_edge].to=v; edge[s_edge].nxt=head[u]; head[u]=s_edge; s_edge++; edge[s_edge].to=u; edge[s_edge].nxt=head[v]; head[v]=s_edge; } void dfs(int x) { vs[x]=1; sumVal[x]=1; maxSub[x]=0; for(int e=head[x];e;e=edge[e].nxt) { int v=edge[e].to; if(!vs[v]) { dfs(v); sumVal[x]+=sumVal[v]; maxSub[x]=Max(maxSub[x],sumVal[v]); } } int k; k=Max(n-sumVal[x],maxSub[x]);//这里 还出过错,最大中的最小、、、 if(k==MIN) mark[cnt++]=x; else if(k<MIN) { MIN=k; cnt=0; mark[cnt++]=x; } return ; } int main() { int i,a,b; scanf("%d",&n); memset(head,0,sizeof(head)); s_edge=0; for(i=1;i<n;i++) { scanf("%d%d",&a,&b); addedge(a,b); } memset(vs,0,sizeof(vs)); cnt=0; MIN=50010; dfs(1); sort(mark,mark+cnt); for(i=0;i<cnt;i++) { if(i==0) printf("%d",mark[i]); else printf(" %d",mark[i]); } printf("\n"); return 0; }