这道题题目就是说给你一个图,然后判断能不能成环,不能成环就输出最长的那一条路。
首先分析问题。怎么判断环?这是图中一个很常见的问题,在无向图中判环我们可以用并查集,在有向图中可以使用tarjan或者拓扑排序。
这个问题是无向图,那么就用并查集就好了,在输入图的过程就可以判断,每当有一条线,我们就找这条线两个端点的父亲,如果父亲一样,那么他们就是构成了环。因为父亲一样说明之前已经两个点用过了并且连在一起(祖先是一样的)那么再连一起,就会构成环。`

int flag = 0;
		for (int i = 1; i <= m; i++) {
			int a = read(), b = read(), c = read();
			int t1 = find_(a), t2 = find_(b);
			if (t1 == t2)flag = 1;//成环
			else {
				pre[t1] = t2;//不是共同祖先则直接连上去
			}
			add_(a, b, c);
			add_(b, a, c);
		}
		if (flag) {
			cout << "YES" << endl;
		}

好了环的问题解决了,我们如何解决最长的路?由于他没有环,那么其实就是可以树,为什么是树?一个联通图里面如果你边数大于n-1那么一定就是有环了, 没环则一定是树,那么求树的最长路就只是求一遍树直径就好了。
树直径怎么求?就是先随便找一个点,然后由这个点出发的最远距离的那个点开始,在走一遍,所得到的的距离就是树直径。这样也就是一个两遍bfs的过程。
但是这又要考虑一个点,由于边数我们是无法确定,所以可能有情况就是,他这个图是有很多很多个联通块。我们就要算出每一个联通块(每一颗树)的直径,取一个max就可以了。
下面贴出程序,有问题可以留言提问,我会尽力解答。程序中bfs1和bfs2完全是一样的,只是一个返回的是点,一个是返回那个最长路的权值。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const long long max_ = 100000 + 50;
int head[max_],n,m,pre[max_],xiann = 1,pan[max_],pan2[max_];
inline int read()
{
	int s = 0, f = 1;
	char ch = getchar();
	while (ch<'0' || ch>'9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0'&&ch <= '9') {
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	return s * f;
}

struct k {
	int next, to, value;
}xian[(1000000+50)*2];
int find_(int x) {
	if (pre[x] == x)return x;
	else
	{
		return pre[x] = find_(pre[x]);
	}
}
void add_(int a, int b, int c) {
	xian[xiann].next = head[a];
	xian[xiann].to = b;
	xian[xiann].value = c;
	head[a] = xiann;
	xiann++;
}
struct kk {
	int node, length;
};
int bfs1(int now) {
	kk temp; temp.node = now; temp.length = 0;
	queue<kk> ans;
	ans.push(temp);
	int maxchang = -1, dian;
	while (!ans.empty()) {
		kk tou = ans.front(); ans.pop();
		if (pan[tou.node] == 1)continue;
		pan[tou.node] = 1;
		for (int i = head[tou.node]; i; i = xian[i].next) {
			int to = xian[i].to;
			if (pan[to] != 1) {
				temp.length = tou.length + xian[i].value; temp.node = to;
				if (temp.length > maxchang) {
					maxchang = temp.length;
					dian = to;
				}
				ans.push(temp);
			}
		}
	}
	return dian;
} 
int bfs2(int now) {
	kk temp; temp.node = now; temp.length = 0;
	queue<kk> ans;
	ans.push(temp);
	int maxchang = -1, dian;
	while (!ans.empty()) {
		kk tou = ans.front(); ans.pop();
		if (pan[tou.node] == 1)continue;
		pan[tou.node] = 1;
		for (int i = head[tou.node]; i; i = xian[i].next) {
			int to = xian[i].to;
			if (pan[to] != 1) {
				temp.length = tou.length + xian[i].value; temp.node = to;
				if (temp.length > maxchang) {
					maxchang = temp.length;
					dian = to;
				}
				ans.push(temp);
			}
		}
	}
	return maxchang;
}

int main() {
	while (cin >> n >> m) {
		for (int i = 1; i <= n; i++) {
			pre[i] = i;
		}
		int flag = 0;
		for (int i = 1; i <= m; i++) {
			int a = read(), b = read(), c = read();
			int t1 = find_(a), t2 = find_(b);
			if (t1 == t2)flag = 1;
			else {
				pre[t1] = t2;
			}
			add_(a, b, c);
			add_(b, a, c);
		}
		if (flag) {
			cout << "YES" << endl;
		}
		else {
			int dian1;
			int aanss = -1;
			for (int i = 1; i <= n; i++) {
				if (pan2[find_(i)] == 0) {
					dian1 = bfs1(i);
					pan2[find_(i)] = 1;
               for (int i = 1; i <= n; i++) pan[i] = 0;
			   int tempp = bfs2(dian1);
			   if (aanss < tempp)aanss = tempp;			
				}
			}
			cout << aanss << endl;
		}
		xiann = 1;
		for (int i = 1; i <= n+1; i++) {
			pan[i] = 0;
			pan2[i] = 0;
			head[i] = 0;
			xian[i].next = xian[i].to =  xian[i].value = 0;
		}
		for (int i = 1; i <=m*2+1; i++) {	
			xian[i].next = xian[i].to = xian[i].value = 0;
		}
	}
	return 0;
	
}