首先,所求解的必须是一棵树,咳咳咳 ,废话一句
树:连通无回路的无向图称为无向树,简称树。
树的直径(Diameter)是指树上的最长简单路。
直径的求法,两次搜索,(bfs or dfs):任选一点w为起点,对树进行搜索,找出离w最远的点u。
然后以u点为起点,再次进行搜索,找出离u点最远的点v,则u到v的路径长度就是树的直径
相对于它的暴力求法,更有关注意义的是它的证明:
1.如果w在直径上,那么u一定是直径的一个端点,反证法:若u不是一个端点的话,肯定存在比到u更长的距离,与假设矛盾。
2.如果w不在直径上,且w到其距离最远点u的路径与直径一定有一个交点c,由1知u是直径的一个端点,如果w到最远点u的路径与直径没有交点,设直径的两端为S与T,那么(w->u)>(w->c)+(c->T),推出(w->u)+(S->c)+(w->c)>(S->c)+(c->T)=(S->T)与假设矛盾。因此w到最远点u的路径与直径必有交点。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
#define maxn 100000
using namespace std;
int n,m,cnt;
int head[maxn];
int mark[maxn];
int ans[maxn];
struct node{
int id;
int d;
int next;
}side[maxn];
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int x,int y,int d)
{
side[cnt].id=y;
side[cnt].d=d;
side[cnt].next=head[x];
head[x]=cnt++;
}
int bfs(int x,int &d)
{
memset(mark,0,sizeof(mark));
queue<node> q;
node tmp;
tmp.id=x;
tmp.d=0;
q.push(tmp);
mark[x]=1;
int mx=0,ans=x;
while(q.size())
{
tmp=q.front() ;
q.pop();
for(int i=head[tmp.id];i!=-1;i=side[i].next)
{
int y=side[i].id;
if(mark[y]) continue;
mark[y]=1;
node nd;
nd.id=y;
nd.d=tmp.d+side[i].d;
if(nd.d>mx)
{
mx=nd.d;
ans=y;
}
q.push(nd);
}
}
d=mx;
return ans;
}
int main()
{
init();
int x,y,w;
while(scanf("%d%d%d",&x,&y,&w)!=EOF)
{
add(x,y,w);
add(y,x,w);
}
int d;
int u=bfs(1,d);
int v=bfs(u,d);
printf("%d\n",d);
return 0;
}
bfs用起来比dfs更加节省时间,本质就是搜索类型不同造成的不同最后是一样的,就是简单的搜索属性,进行遍历寻找最大长度。