Mainly with the help of this relatively bare topic to talk about Tarjan this algorithm
Tarjan is an algorithm for solving the linear time of a strongly connected component of a forward graph. (implemented with DFS)
If two vertices can be connected to each other, the two vertices are strongly connected. If there is strong connectivity to every two vertices of the graph G, the G is a strongly connected graph. A strongly connected sub-graph of a forward graph, called a strongly connected component.
In this graph above, 1,2,3,4 form a strong connected component, while 1,2,4, and 1,3,4 are not (because they are not very strong connected sub-graphs).
Tarjan is implemented with DFS (we can indent the graph after using Tarjan (of course, this is not used).
The problem is to find the largest strong connected component, and the sequence number of the strong connected component from small to large output (if there is the same large strong connectivity components, then the output contains a smaller point of the one)
Here's the question: (Tarjan code plus comment down)
Topic
Title Description Description in Gensokyo, the Kamishirasawa sound is a teacher famous for his knowledge. Spring snow changes cause many roads in the world to be blocked by heavy snow, so that some students can not successfully reach the village where the Hui sound. So the comet decided to change to a village that could gather the largest number of people as a new teaching location. The earth is made up of N villages (numbered 1). N) and M Road, the road is divided into two kinds of one-way, one for two-way passage, respectively, with 1 and second mark. If there is a pathway from village A to village B, then we think we can reach village B from village A, which is recorded as (A, b). When (A, b) and (b,a) are satisfied at the same time, we think that A, B is absolutely connected, recorded as<A,B>. An absolute connected area is a collection of villages in which any two villages, X, Y, meet <X,Y>. Now your task is to find the largest absolute connected area and output The villages of this absolutely connected area sequentially. If there are two largest, the output dictionary order is minimal, for example, when there is 1,3, 4 and 2,5, 6 of these two maximum connected areas, the output is 1,3,4. Enter a description input description line 1th: Two positive integers n,m 2nd. M+1 rows: Three positive integers per line a,b,t, T = 1 means that there is a one way road from village A to B, t =2 indicates that there is a two-way road between Village A and B. Ensure that each road appears only once. Output Description Line 1th: 1 integers representing the maximum number of villages included in the absolute connected area. Line 2nd: A number of integers, sequentially outputting the largest absolute connected area that contains the village number. Sample input to sample5 51 2 11 3 22 4 25 1 23 5 1sample output Sample outputs31 3 5data range and tips&Hint for% of data: N <= 200 and M <=Ten, thefor% of data: N <=5, 000 and M <= -, the
View Code
It's obvious that this problem needs to be tarjan.
#include <stdio.h>#include<algorithm>using namespacestd;intdfn[500000], low[500000], stack[900000], J, number, N, m, x, Y, W, hh[600000], CNT, top, C, q, ans, yy[100000];intcolor[400000], u, num, p[400000];BOOLd[500000];structnode{intNext, Z, E;} b[110000];voidAddintAaintBB)//adjacency table {b[++CNT].E =BB; B[cnt].next=HH[AA]; HH[AA]=CNT;}
Tarjan Code:
intTarjan (intk) { inti; DFN[K]= Low[k] = + +The NUMBER;//DFN record is the real time to access this node, and the low record is stack[++top] =K; Put the current point into the stack d[k]=true;//This is the state that represents the point K for(i = hh[k]; I! =0; i =B[i].next) { if(!DFN[B[I].E]) If the current node does not have access to continue to search {Tarjan (B[I].E); LOW[K]=min (low[k], low[b[i].e]); } Else if(D[B[I].E] = =true) {Low[k]=min (low[k], dfn[b[i].e]);
Of course can also be written low[k]=min (LOW[K],LOW[B[I].E]); } } if(Dfn[k] = =low[k])//If the point is the root of a strongly connected component, that is, we have found a strong connected component, start the stack {color[k]= ++num;//Dye All the points on the strong connected component into the same color . while(1) {P[num]++;//Record the point on the strong connected component D[stack[top]]=false;//stack top element out stack color[stack[top--]] =num; dye the top element of the stack to the color of the current strong connected componentif(Stack[top +1] = = k) Break;//Because the root is definitely the first access on the current strongly connected component, which is the first inbound, so pops up the root to represent the full popup on the strong connected component} return 0;}
intMain () {inti; scanf ("%d%d", &n, &m); U=1; for(i =1; I <= m; i++) {scanf (" %d%d%d", &x, &y, &W); if(W = =1) Add (x, y);//Build EdgeElse{Add (x, y); Add (y, x); } } for(j =1; J <= N; J + +) { if(!Dfn[j]) Tarjan (j);//If the current point has not been searched, deep Search from the current point} for(i =1; I <= N; i++) { if(P[color[i]] > ans) ans = p[color[i]], u =i; } printf ("%d\n", ans); for(i =1; I <= N; i++) { if(Color[i] = = Color[u]) printf ("%d", i); } return 0;}
Tarjan Explanation (with codevs1332 (Tarjan's bare title)