Judging whether there is a loop or not, I personally think it is more efficient to query and query sets, and the complexity is lower than that of DFS, which is very cost-effective.
First, judge whether there is a ring. If there is no ring, output the longest path.
We can think of an undirected graph. If there is no ring, there must be two forms: one is a tree and the other is a forest.
If the longest path is required, that is, the radius of the tree is required.
The general idea is clear. Let's talk about the details.
The idea of querying sets is to find a node in the graph as the root. All points in a connected component are inserted to this root, yes, this is the root or the front-end is the root. Because of the maintenance of the query set, the data structure here is very efficient. You can check the specific content in the book. An important property is that if the root of the two points of an edge is one, it means that the edge is added, and a ring exists in the graph. It is obvious to draw a graph.
For details, seeCode:
# Include <cstdio> # include <cstring> # include <algorithm> # include <iostream> using namespace STD; const int n = 100022; int f [N], num [N]; int find (int x) {return (F [x] = x )? X: F [x] = find (F [x]);} int main () {int n, m, T1, T2; int U, V, W; int ans; bool FL; while (scanf ("% d", & N, & M )! = EOF) {for (INT I = 1; I <= N; I ++) f [I] = I; memset (Num, 0, sizeof (Num )); FL = true; ans = 0; while (M --) {scanf ("% d", & U, & V, & W ); t1 = find (U); // find the parent node t2 = find (V); If (! FL) continue; If (T1 = t2) FL = false; else {f [T1] = t2; // connects two connected components, that is, to change one parent node to the parent node num [T2] + = num [T1] + W of the other parent node; If (ANS <num [T2]) ans = num [T2] ;}}if (FL) {printf ("% d \ n", ANS); Continue ;}printf ("Yes \ n ");}}