算法筆記--樹的直徑模板
阿新 • • 發佈:2017-11-29
找到 stdin () color ref b- 個性 sync .org
思路:
利用了樹的直徑的一個性質:距某個點最遠的葉子節點一定是樹的某一條直徑的端點。
先從任意一頂點a出發,bfs找到離它最遠的一個葉子頂點b,然後再從b出發bfs找到離b最遠的頂點c,那麽b和c之間的距離就是樹的直徑。
模板:
const int N=1e6+5; int head[N]; int dis[N]; bool vis[N]; int cnt=0,b,mxn=0; struct edge { int to,w,next; }edge[N]; void add_edge(int u,int v,int w) { edge[cnt].to=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } void bfs(int s) { queue<int>q; q.push(s); int now,nxt; mxn=0; b=s; mem(dis,0); mem(vis,false); while(!q.empty()) { now=q.front(); q.pop(); for(inti=head[now];~i;i=edge[i].next) { if(!vis[edge[i].to]) { q.push(edge[i].to); vis[edge[i].to]=true; dis[edge[i].to]=dis[now]+edge[i].w; if(dis[edge[i].to]>mxn) { mxn=dis[edge[i].to]; b=edge[i].to; } } } } }
poj 2631 Roads in the North
代碼:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e6+5; int head[N]; int dis[N]; bool vis[N]; int cnt=0,b,mxn=0; struct edge { int to,w,next; }edge[N]; void add_edge(int u,int v,int w) { edge[cnt].to=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } void bfs(int s) { queue<int>q; q.push(s); int now,nxt; mxn=0; b=s; mem(dis,0); mem(vis,false); while(!q.empty()) { now=q.front(); q.pop(); for(int i=head[now];~i;i=edge[i].next) { if(!vis[edge[i].to]) { q.push(edge[i].to); vis[edge[i].to]=true; dis[edge[i].to]=dis[now]+edge[i].w; if(dis[edge[i].to]>mxn) { mxn=dis[edge[i].to]; b=edge[i].to; } } } } } int main() { ios::sync_with_stdio(false); cin.tie(0); int u,v,w; mem(head,-1); //freopen("in.txt","r",stdin); while(cin>>u>>v>>w)add_edge(u,v,w),add_edge(v,u,w); bfs(1); //cout<<b<<‘ ‘<<mxn<<endl; bfs(b); cout<<mxn<<endl; //fclose(stdin); return 0; }View Code
算法筆記--樹的直徑模板