The first problem of the Tarjan algorithm
Spray on my face .... Handwritten folds open into bool, I've been looking for the wrong ...
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAXN 100005const int mod=1000000007;using namespace std;struct node{int to,next;} Edge[maxn*3];int dfn[maxn],low[maxn],head[maxn],a[maxn],s[maxn];bool instack[maxn];int Cnt,n,m,c,top;long Long ans1 , ans2;void Add (int x,int y) {edge[cnt].to = y; Edge[cnt].next = Head[x]; head[x]=cnt++;} void Tarjan (int x) {dfn[x]=low[x]=++c; Instack[x] = true; S[++top]=x; for (int i=head[x];i!=-1;i=edge[i].next) {int tmp = EDGE[I].TO; if (!dfn[tmp]) {Tarjan (TMP); if (Low[x]>low[tmp]) low[x] = low[tmp]; } else if (Instack[tmp]) {if (low[x]>dfn[tmp]) low[x] = dfn[tmp]; }} if (Low[x]==dfn[x]) {int t; int minx = Mod,sum = 0; do{t = s[top--]; Instack[t] = false; if (A[t]<minx) { Minx = a[t]; sum = 1; } else if (a[t] = = Minx) sum++; }while (t!=x); Ans1+=minx; Ans2= (ans2*sum)%mod; }}int Main () {int p,b; while (scanf ("%d", &n)!=eof) {cnt = 0; memset (head,-1,sizeof (head)); memset (instack,0,sizeof (instack)); memset (dfn,0,sizeof (DFN)); memset (low,0,sizeof (Low)); Memset (s,0,sizeof (s)); for (int i=1;i<=n;i++) scanf ("%d", &a[i]); scanf ("%d", &m); for (int i=1;i<=m;i++) {scanf ("%d%d", &p,&b); Add (p,b); } c = 0,top = 0,ans1 = 0,ans2 = 1; for (int k=1;k<=n;k++) {if (!dfn[k]) Tarjan (k); } printf ("%i64d%i64d\n", ans1,ans2); } return 0;}
The base of the Tarjan algorithm is DFS.
We prepare two arrays of low and DFN. The low array is an array of tokens that record the DFN value of the root node of the search subtree where the strongly connected sub-graph of the point resides (very Raozui, as you will see clearly). The DFN array records the time of the search to that point, that is, the first few searches for this point. According to the following rules. After searching through the graph (without backtracking) and the operation of the stack, we can get the strong connected component of the forward graph.
- Initialization of the array: When the point p is first searched. The value of the DFN and the low array is the time to that point.
- Stack: Every search to a point, press it into the top of the stack.
- When the point P is connected to the point P ', it is assumed that the P ' is not in the stack at this time (Dfn[p]. The low value of P is the smaller of the lower value of two points.
- When the point P has a connection to the point P ', assume that at this time (Dfn[p]) p ' is in the stack. The low value of P is the lower of P and the smaller of the DFN value of P '.
- Whenever the search to a point has passed the above operation (that is, the subtree has all traversed) the low value equals the DFN value, then it and the element above it pops up the stack. These elements of the stack form a strong connected component.
- Continue searching (may change the starting point of the search, as the entire graph may be divided into two disconnected parts). Until all points are traversed.
Because each vertex is only visited once. Each edge was only visited once. We can find the strong connected component of the graph in O (n+m) time. But what is the reason for doing so?
The operating principle of the Tarjan algorithm is as follows:
- The Tarjan algorithm is based on the theorem: in whatever depth-first search, all vertices within the same strong connected component are in the same depth-first search tree. In other words, the strongly connected component must be a deep search tree subtree of the graph.
- Can prove. When a point is both a point in a strongly connected sub-graph Ⅰ and a point in a strongly connected sub-graph Ⅱ, it is a point in the strongly connected sub-graph Ⅰ∪ⅱ.
- In this way, we use the low value to record the DFN value of the root node of the search subtree corresponding to the strong connected sub-graph of the point.
Note that the elements in the subtree must be contiguous in the stack, and the root node must be at the bottom of all the subtree elements in the stack.
- The strongly connected component is made up of several rings.
So when a loop is formed (that is, the next point of the search is already in the stack). We unify the low value of this path, that is, the points on this path belong to the same strong connected component.
- Assuming that the DFN value of a point is equal to the low value after traversing the entire search tree, it is the root of the search subtree.
Then, it's above (it contains its own) all the elements are stacked to make up the strong connected component.
From the letter above: http://www.cnblogs.com/saltless
Cf:problem 427c-checkposts good communication Tarjan algorithm