求樹的最長直徑,之前做過hdu2196,套用那道題的思路,兩次dfs,求出每個結點的最長直徑,然後找出最大的即爲整棵樹的最長直徑#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#define M 100010
#define ME 1000010
using namespace std;
struct node{
int to,val,next;
}edge[ME*2];
int head[M];
int tot;
int n,m;
int len[M],len2[M],lenid[M];
bool vis[M];
int ans;
void insert(int u,int v,int val){
edge[tot].to=v;
edge[tot].val=val;
edge[tot].next=head[u];
head[u]=tot++;
}
bool dfs(int u,int pre){ //判環
vis[u]=true;
int i,v;
for(i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(v==pre) continue;
if(vis[v]||dfs(v,u)) return true;
}
return false;
}
void dfs1(int u,int pre){
vis[u]=false;
len[u]=len2[u]=0;
int i,v;
for(i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(v==pre) continue;
dfs1(v,u);
if(len[v]+edge[i].val>len[u]){
len2[u]=len[u];
len[u]=len[v]+edge[i].val;
lenid[u]=v;
}
else if(len[v]+edge[i].val>len2[u]){
len2[u]=len[v]+edge[i].val;
}
}
}
void dfs2(int u,int pre){
int i,v;
for(i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(v==pre) continue;
if(lenid[u]==v){
if(len2[u]+edge[i].val>len[v]){
len2[v]=len[v];
len[v]=len2[u]+edge[i].val;
lenid[v]=u;
}
else if(len2[u]+edge[i].val>len2[v]){
len2[v]=len2[u]+edge[i].val;
}
}
else{
if(len[u]+edge[i].val>len[v]){
len2[v]=len[v];
len[v]=len[u]+edge[i].val;
lenid[v]=u;
}
else if(len[u]+edge[i].val>len2[v]){
len2[v]=len[u]+edge[i].val;
}
}
dfs2(v,u);
ans=max(ans,len[v]);
}
}
int main(){
int i,u,v,val;
while(scanf("%d%d",&n,&m)!=EOF){
tot=0;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
for(i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&val);
insert(u,v,val);
insert(v,u,val);
}
for(i=1;i<=n;i++)
if(!vis[i])
if(dfs(i,-1))
break;
if(i<=n)
printf("YES\n");
else{
ans=0;
for(i=1;i<=n;i++)
if(vis[i]){
dfs1(i,-1);
ans=max(ans,len[i]);
dfs2(i,-1);
}
printf("%d\n",ans);
}
}
return 0;
}
還有一種更合適的方法,一次dfs即可求出一棵樹的最長直徑,len[i]表示以i爲根結點的樹的最長直徑,len2[i]表示以i爲根結點的樹且以i爲起點的最長直徑
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#define M 100010
#define ME 1000010
using namespace std;
struct node{
int to,val,next;
}edge[ME*2];
int head[M];
int tot;
int n,m;
int len[M],len2[M];
bool vis[M];
int ans;
void insert(int u,int v,int val){
edge[tot].to=v;
edge[tot].val=val;
edge[tot].next=head[u];
head[u]=tot++;
}
bool dfs(int u,int pre){
vis[u]=true;
int i,v;
for(i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(v==pre) continue;
if(vis[v]||!dfs(v,u)) return false;
}
return true;
}
void dfs1(int u,int pre){
vis[u]=false;
len[u]=len2[u]=0;
int i,v,temp;
for(i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(v==pre) continue;
dfs1(v,u);
temp=len2[v]+edge[i].val+len2[u];
if(temp>len[u])
len[u]=temp;
if(len2[v]+edge[i].val>len2[u])
len2[u]=len2[v]+edge[i].val;
}
if(len[u]>ans)
ans=len[u];
}
int main(){
int i,u,v,val;
while(scanf("%d%d",&n,&m)!=EOF){
tot=0;
bool end=false;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
for(i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&val);
insert(u,v,val);
insert(v,u,val);
}
for(i=1;i<=n;i++)
if(!vis[i])
if(!dfs(i,-1))
break;
if(i<=n)
printf("YES\n");
else{
ans=0;
for(i=1;i<=n;i++)
if(vis[i])
dfs1(i,-1);
printf("%d\n",ans);
}
}
return 0;
}