码迷,mamicode.com
首页 > 其他好文 > 详细

HDU ACM 4514 湫湫系列故事——设计风景线->树上环的判断+树上最长路

时间:2015-06-08 09:55:31      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:c   c++   acm   算法   编程   

题意:一个无向图,首先判定是否成环,然后求一条最长链。
分析:成环用并查集判断,最长链就是树形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 湫湫系列故事——设计风景线->树上环的判断+树上最长路

标签:c   c++   acm   算法   编程   

原文地址:http://blog.csdn.net/a809146548/article/details/46404301

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!