首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【HDU】4514 - 湫湫系列故事——设计风景线(树的直径 & 并查集 & dfs)

【HDU】4514 - 湫湫系列故事——设计风景线(树的直径 & 并查集 & dfs)

作者头像
FishWang
发布2025-08-26 15:07:40
发布2025-08-26 15:07:40
18200
代码可运行
举报
运行总次数:0
代码可运行

点击打开题目

湫湫系列故事——设计风景线

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 4005 Accepted Submission(s): 716

Problem Description

  随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。   现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少?   其中,可以兴建的路线均是双向的,他们之间的长度均大于0。

Input

  测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述;   接下去m行,每行3个数字u v w,分别代表这条线路的起点,终点和长度。 [Technical Specification]   1. n<=100000   2. m <= 1000000   3. 1<= u, v <= n   4. w <= 1000

Output

  对于每组测试数据,如果能够建成环形(并不需要连接上去全部的风景点),那么输出YES,否则输出最长的长度,每组数据输出一行。

Sample Input

代码语言:javascript
代码运行次数:0
运行
复制
   3 3
1 2 1
2 3 1
3 1 1

Sample Output

代码语言:javascript
代码运行次数:0
运行
复制
   YES

Source

2013腾讯编程马拉松初赛第二场(3月22日)

这个题本来并查集 + 树的直径就可以做了,但是有一点要特别注意:图的连通分量可能不止一个,即:可能不止有一棵树。

代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MAX 100000
int n,m;
int root[MAX+11];
vector<int> mapp[MAX+5];
vector<int> dis[MAX+5];
int f[MAX+5];		//距离当前点的距离 
bool vis[MAX+5];
void init()
{
	for (int i = 1 ; i <= n ; i++)
	{
		mapp[i].clear();
		dis[i].clear();
		root[i] = i;
	}
}
int find(int x)
{
	if (x != root[x])
		root[x] = find(root[x]);
	return root[x];
}
bool join(int x,int y)
{
	int fx,fy;
	fx = find(x);
	fy = find(y);
	if (fx != fy)
	{
		root[fx] = fy;
		return true;
	}
	return false;
}
int dfs(int x)
{
	int ans;		//最远点 
	int maxx = 0;		//最大距离 
	queue<int> q;		//存放根 
	CLR(vis,false);
	CLR(f,0);
	f[x] = 0;
	q.push(x);
	while (!q.empty())
	{
		int st = q.front();
		q.pop();
		vis[st] = true;
		for (int i = 0 ; i < mapp[st].size() ; i++)
		{
			if (!vis[mapp[st][i]])		//该点没有用过 
			{
				q.push(mapp[st][i]);
				f[mapp[st][i]] = f[st] + dis[st][i];
				if (f[mapp[st][i]] > maxx)
				{
					maxx = f[mapp[st][i]];
					ans = mapp[st][i];		//记录节点 
				}
			}
		}
	}
	return ans;
}
int main()
{
	while (~scanf ("%d %d",&n,&m))
	{
		init();
		bool circle = false;		//是否成环 
		for (int i = 1 ; i <= m ; i++)
		{
			int t1,t2,t3;
			scanf ("%d %d %d",&t1,&t2,&t3);
			mapp[t1].push_back(t2);
			dis[t1].push_back(t3);
			mapp[t2].push_back(t1);		//求树的直径一定要双向存图 
			dis[t2].push_back(t3);
			if (!join(t1,t2))
				circle = true;
		}
		if (circle)
		{
			printf ("YES\n");
			continue;
		}
		int maxx = 0;
		for (int i = 1 ; i <= n ; i++)
		{
			if (root[i] == i)
			{
				int st = dfs(i);		//树的连通分量可能不止一个 
				int ans = dfs(st);
				maxx = max (maxx , f[ans]);
			}
		}
		printf ("%d\n",maxx);
	}
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 湫湫系列故事——设计风景线
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档