POJ3107 Godfather 求樹的重心
阿新 • • 發佈:2019-01-30
題目大意:求樹的重心,如果有多個節點,按節點編號升序輸出所有的。
分析:用vector儲存圖會TLE,這裡用了前向星儲存圖,用set來記錄節點可以省去排序(set是一顆二叉樹,自動把加入的點按升序排列了)。
實現程式碼如下:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <set> using namespace std; const int maxn=50005; struct note { int v,next; }edge[maxn*2]; int head[maxn],ip; int maxx,n,num[maxn]; set <int> point; void init() { memset(head,-1,sizeof(head)); ip=0; } void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++; } void dfs(int u,int pre) { int tmp=-0x3f3f3f3f; num[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==pre)continue; dfs(v,u); num[u]+=num[v]; tmp=max(tmp,num[v]); } tmp=max(tmp,n-num[u]); if(tmp<=maxx) { if(tmp<maxx) { point.clear(); point.insert(u); maxx=tmp; } else if(tmp==maxx) point.insert(u); } } int main() { while(scanf("%d",&n)!=-1) { init(); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } memset(num,0,sizeof(num)); maxx=0x3f3f3f3f; dfs(1,-1); set <int> ::iterator it; bool first=true; for(it=point.begin();it!=point.end();it++) { if(first) { printf("%d",*it); first=false; } else printf(" %d",*it); } printf("\n"); } return 0; }