求树的直径【两遍BFS】
两遍BFS。从任意一个点出发,第一遍可以找到直径的一端,从这端出发即可找到另外一端。
证明:从U点出发,到达V【画个图便清晰了】
1.如果U在直径上,则V一定是直径的一个端点。
2.如果U不在直径上。U,V线一定和直径有交点(如果没有交点,从U引一条路到直径交于U'。【反证】)。有交点则V一定是直径另一端。
代码:【举例】
int path(int x){ //从x出发,求直径 mem(vis,-1); while(!Q.empty()) Q.pop(); Q.push(x); vis[x]=0; while(!Q.empty()){ int u=Q.front(); Q.pop(); int L=G[u].size(); rep(i,0,L-1){ int v=G[u][i]; if(g[u][v]==1 && vis[v]==-1){ vis[v]=vis[u]+1; Q.push(v); } } } int ans=-1; int vv=-1; rep(i,1,n){ if(vis[i]>ans){ ans=vis[i]; vv=i; } } while(!Q.empty()) Q.pop(); mem(vis,-1); Q.push(vv); vis[vv]=0; while(!Q.empty()){ int u=Q.front(); Q.pop(); int L=G[u].size(); rep(i,0,L-1){ int v=G[u][i]; if(g[u][v]==1 && vis[v]==-1){ vis[v]=vis[u]+1; Q.push(v); } } } ans=-1; rep(i,1,n){ if(vis[i]>ans){ ans=vis[i]; } } return ans; }