题意:一个无向图,首先判定是否成环,然后求一条最长链。
分析:成环用并查集判断,最长链就是树形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