题意:一个无向图,首先判定是否成环,然后求一条最长链。
分析:成环用并查集判断,最长链就是树形dp了。
#include<iostream>
#include<vector>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define N 100005
int ans;
int dp[N]; //dp[i]表示i节点为根节点树的最长路
int p[N];
struct Edge
{
Edge(int _v,int _f):v(_v),f(_f){}
int v,f;
};
vector<Edge> map[N];
#define max(a,b) ((a)>(b)?(a):(b))
int Find(int x)
{
return x==p[x]?x:x=Find(p[x]);
}
void dfs(int p,int u) //u是父节点,v是子节点
{
int maxtmp,i,v,f;
maxtmp=0;
for(i=0;i<map[u].size();i++)
{
v=map[u][i].v;
f=map[u][i].f;
if(v==p) continue;
dfs(u,v);
ans=max(ans,dp[v]+f+maxtmp); //ans计算以u为根节点的两棵最长子树权值的和
maxtmp=max(maxtmp,dp[v]+f);
}
dp[u]=maxtmp;
}
int main()
{
int n,m,a,b,c,x,y,i;
bool loop;
while(scanf("%d%d",&n,&m)==2)
{
ans=0;
loop=false;
for(i=1;i<=n;i++)
{
dp[i]=-1;
p[i]=i;
map[i].clear();
}
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(loop) continue;
x=Find(a);
y=Find(b);
if(x!=y) p[x]=y;
else
{
loop=true;
continue;
}
map[a].push_back(Edge(b,c));
map[b].push_back(Edge(a,c));
}
if(loop)
{
puts("YES");
continue;
}
for(i=1;i<=n;i++) //防止树不是连通的
if(dp[i]==-1) dfs(0,i);
printf("%d\n",ans);
}
return 0;
}
HDU ACM 4514 湫湫系列故事——设计风景线->树上环的判断+树上最长路
原文地址:http://blog.csdn.net/a809146548/article/details/46404301