题目:http://poj.org/problem?id=2631
树的直径:遍历两遍,第一遍遍历找到权值和最大的点及树的直径的某一个端点,然后已这个端点为起点继续遍历整个树,找到权值和最大的点。这两个端点及是树的直径的两个端点
dfs:
#include<cstdio>
#include<algorithm>
#include<cstring>
#define len 10005
using namespace std;
struct node
{
int j,v,next;
}s[len*10];
int head[len],ans,p,k,n=-1;
bool vis[len];
void add(int a,int b,int c)
{
s[k].j=b;
s[k].v=c;
s[k].next=head[a];
head[a]=k++;
}
void dfs(int x,int sum)
{
if(x>n) return ;
if(ans<sum) ans=sum,p=x;
for(int i=head[x];i!=-1;i=s[i].next)
{
int j=s[i].j;
if(!vis[j])
{
vis[j]=1;
dfs(j,sum+s[i].v);
vis[j]=0;
}
}
}
int main()
{
int a,b,c;
k=0;
memset(head,-1,sizeof(head));
while(scanf("%d%d%d",&a,&b,&c)!=EOF)
{
add(a,b,c);
add(b,a,c);
n=max(max(a,b),n);
}
for(int i=0;i<=n;i++) vis[i]=0;
ans=0;
vis[1]=1;
dfs(1,0);
for(int i=0;i<=n;i++) vis[i]=0;
ans=0;
vis[p]=1;
dfs(p,0);
printf("%d\n",ans);
return 0;
}
bfs:
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define len 10005
#define inf 100000000
using namespace std;
struct node
{
int j,v,next;
}s[len*10];
bool vis[len];
int head[len],d[len],ans,p,k,n=-inf;
void add(int a,int b,int c)
{
s[k].j=b;
s[k].v=c;
s[k].next=head[a];
head[a]=k++;
}
void bfs(int t)
{
vis[t]=1;
d[t]=0;
ans=0;
queue<int> q;
q.push(t);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i!=-1;i=s[i].next)
{
int j=s[i].j;
if(d[j]>d[x]+s[i].v||vis[j]) continue;
d[j]=d[x]+s[i].v;
if(ans<d[j]) ans=d[j],p=j;
vis[j]=1;
q.push(j);
}
}
}
void init()
{
for(int i=1;i<=n;i++)
{
vis[i]=0;
d[i]=-inf;
}
}
int main()
{
int a,b,c;
k=0;
memset(head,-1,sizeof(head));
while(~scanf("%d%d%d",&a,&b,&c))
{
add(a,b,c);
add(b,a,c);
n=max(max(a,b),n);
}
init();
bfs(1);
init();
bfs(p);
printf("%d\n",ans);
return 0;
}