思路:
利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点。
先从任意一顶点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(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; } } } } }
代码:
#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; }
时间: 2024-10-10 11:27:12