【树的直径】 ZJU 3820 Building Fire Stations
先找到树的直径 len 再将直径均匀分成两根。。
如果不能平分则需要比较 max((len/2 和len/2-1 ),(len/2 和len/2+1 ))
#include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <cmath> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #define cler(arr, val) memset(arr, val, sizeof(arr)) #define FOR(i,a,b) for(int i=a;i<=b;i++) #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 200000; const int MAXM = 200000; const int INF = 0x3f3f3f3f; const int mod = 1000000007; const double eps= 1e-8; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 struct Edge { int to,next; } edge[MAXN*2]; int head[MAXN],pre[MAXN],d[MAXN],tol; bool vis[MAXN]; void init() { tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v) { edge[tol].to=v,edge[tol].next=head[u]; head[u]=tol++; edge[tol].to=u,edge[tol].next=head[v]; head[v]=tol++; } int bfs(int u,int no) { int point=u,big=0; memset(vis,false,sizeof(vis)); queue<int>q; q.push(u); vis[u]=vis[no]=true; pre[u]=-1; d[u]=1; while(!q.empty()) { u=q.front(); q.pop(); for(int i=head[u]; ~i; i=edge[i].next) { int v=edge[i].to; if(!vis[v]) { d[v]=d[u]+1; pre[v]=u; if(d[v]>big) { big=d[v]; point=v; } vis[v]=true; q.push(v); } } } return point; } void solve(int s,int e,int &out1,int &out2,int &ans) { int u,v; u=bfs(s,e); v=bfs(u,e); int star[MAXN]; int len1=0,tmp; tmp=v; while(tmp!=-1) { star[len1++]=tmp; tmp=pre[tmp]; } out1=star[(len1)/2]; ans=(len1)/2; u=bfs(e,s); v=bfs(u,s); int len2=0; tmp=v; while(tmp!=-1) { star[len2++]=tmp; tmp=pre[tmp]; } out2=star[(len2)/2]; ans=max(ans,len2/2); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif int t,a,b,n; scanf("%d", &t); while(t--) { int star[MAXN]; init(); scanf("%d", &n); for(int i=0; i<n-1; i++) { scanf("%d%d",&a,&b); addedge(a,b); } int u=bfs(1,n+1); int v=bfs(u,n+1); int tmp,num=0,ans,out1,out2; int len=0; tmp=v; while(tmp!=-1) { star[len++]=tmp; tmp=pre[tmp]; } int s=star[(len)/2]; int e=star[(len)/2-1]; solve(s,e,out1,out2,ans); if(len%2==1) { int s=star[(len)/2]; int e=star[(len)/2+1]; int out3,out4,ans2; solve(s,e,out3,out4,ans2); if(ans2>ans) out1=out3,out2=out4; } printf("%d %d %d\n",ans,out1,out2); } return 0; }