tarjan algorithm more detailed explanation && && tarjan common troubleshooting Los P2002 Valley spread the message explanations

Because of big brother to write longer and more specific than me, so I will write about sum up the

Introduction:

As we all know, many of the figures there is something called the ring.

For this algorithm a lot of things are a headache. (Suchas Dijkstra)

Deeper: ring belonging to the strong link component (Strongly Connected Components) :

Definition: If there are strongly connected to each of the two vertices of G, said G is a strongly connected graph. There are a great strength to FIG connected subgraph, called strongly connected components.

For example :( painting skilled to autistic )

 

China Unicom is the strong component inside the red circle.

For this thing, other algorithms more difficult to do;

So we put this thing to a close, or to find out all of the elements belong to a strong Unicom component, or some other action, a call tarjan who developed a tarjan algorithm.

Rectification of names for him: Tarjan , listen how to read.

For tarjan algorithm for strong link component, the steps of:

1. Define two arrays dfn and low,

DFN [x] represents the x node is the first to be traversed several.

Low [x] represents the minimum value of the x dfn and all its sub-tree edges.

2, we use a stack to store traverse to the point, the current search to the marked point in the stack record is true.

3, for each child of the current node, if not previously traversed, to traverse down, and takes low value after traversing min: low [X] = min (low [X], low [V]) . If you already traversed before traversing to, that is in [v] = 1, then we will not continue down the search, direct transfer of value dfn: Low [the X-] = min (Low [the X-], dfn [v ]) ;

4, if the value of the current node dfn equal to the value of low, due to the low value represents the smallest dfn of the current node and all its sub-tree edges, then we can think low is passed in a circle back to the current dfn, also found a strong representative of China Unicom component, then we put all the current top of the stack is popped from the stack until the current element in the elements as part of a strong component of China Unicom.

Algorithms main frame is completed, the nature of deep search.

In particular, a node can be considered a strong component of China Unicom, since it themselves to themselves. . .

On the code:

 

void Tarjan ( int U) { 
    DFN [U] = ++ IND; 
    low [U] = DFN [U]; // DFN low and initialization, the initial value DFN low current, low may be sub-node update. 
    S [Top ++] = U; // S representatives stack used to keep the strong link component. 
    in [U] = . 1 ; // in stack tag to bool array 
    for ( int I = head [U]; I; I = E [I] .next) { // before the chain StarRam FIG 
        int V E = [I] .to; // the side 
        IF (DFN [V] == 0 ) { // if not been to 
            Tarjan (V); // continue searching down 
            low [u] = min (low [u ], Low [V]); //Update low value 
        } the else { // Bian Li Le DAO, zi and V Bu Zai Shu Li Mian 
            IF ( in [V]) { // Zai Li Mian Zhan 
                low [U] = min (low [U], DFN [V ]); // update, but why not dfn is Low, the following Detailed 
            } 
        } 
    } 
    IF (dfn [U] == Low [U]) { // a strong root component Unicom 
        cnt_scc ++; // for marking Unicom strong current component ID 
        the while (! S [Top] = U) { // continue to pop up to the current node projectile 
            top-- ;
             in [S [Top]] = 0 ; 
            SCC [S [Top]] = cnt_scc ;// Tarjan major role, mark the current point is in the first few strong Unicom component (may also be used as condensing point) 
        } 
    } 
}

 

So, Luo Valley p2002 This question is also very well done.

Ideas:

Obviously, for each component of a strong internal Unicom, as long as there is a point to be transferred to the message, then the other points can be transferred to the message.

Then we will all strong Unicom components shrink to a point, then all the statistics of the strong component of China Unicom, the answer is zero if you need to add a component to ensure that the current strong Unicom and its children were able to be passed to the information.

code:

#include <cstdio> 
#include <the iostream>
 the using  namespace STD; 

int n-
 int m;
 int FRO;
 int T;
 int sccnum = 0 ;
 int Ru [ 100001 ]; // represents the intensity i of the presence or absence of Unicom component (bool may be) 
int NUM = 0 ;
 int ANS = 0 ;
 int DFN [ 100001 ];
 int Low [ 100001 ];
 int head [ 100001 ];
 int Stack [ 100001 ];
int top;
int cnt=0;
int belong[100001];
bool in[100001];

struct edge{
    int to,next;
}edg[500002];

inline int read()//自研快读 
{
    int ans=0;
    char ch=getchar(),last=' ';
    while(ch<'0'||ch>'9')last=ch,ch=getchar();
    while(ch>='0'&&ch<='9')ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    return last=='-'?-ans:ans;
}

inline void add(int from,int to)//链式存图 
{
    num++;
    edg[num].to=to;
    edg[num].next=head[from];
    head[from]=num;
}

void tarjan(int x)//主体部分 
{
    stack[top++]=x;
    dfn[x]=low[x]=++cnt;
    in[x]=1;
    for(int i=head[x];i;i=edg[i].next)
    {
        int v=edg[i].to;
        if(!dfn[v])
        {
            tarjan(v);
            low[x]=min(low[x],low[v]);
        }
        else if(in[v])
        {
            Low [X] = min (Low [X], DFN [V]); 
        } 
    } 
    IF (DFN [X] == Low [X]) 
    { 
        sccnum ++ ;
         the while (! Stack [Top] = X) 
        { 
            Top - ;
             in [Stack [Top]] = 0 ; 
            belong [Top] Stack [] = sccnum; // marked as a strong component Unicom 
        } 
    } 
} 

int main () { 
    n- = Read (), m = Read () ;
     for ( int I = . 1 ; I <= m; I ++ ) 
    { 
        FRO = Read (), T = Read ();
         IF (FRO =! T) the Add (FRO, T); 
    } 
    for ( int I = . 1 ; I <= n-; I ++) / / for each point to run a Tarjan 
    {
         IF (! Tarjan (I) DFN [I]); 
    } 
    for ( int I = . 1 ; I <= n-; I ++ ) 
    { 
        for ( int J = head [I]; J; EDG = J [J] .next) // through each point of the statistical component of the strong link 
        {
             int V = EDG [J] .to;
             IF ! (belong [I] = belong [V]) Ru [belong [V]] = . 1 ; 
        } 
    } 
    for ( int I = . 1 ; I <= sccnum; I ++) // if the degree is 0, the answer to add a 
    {
         IF ANS ++ (Ru [I]!) ; 
    } 
    the printf ( " % D " , ANS); // end 
    return  0 ; 
}

 The end of the main part of the article.

Dfn and low of controversy: when the low take min, why not low [v] and use dfn [v]?

This issue is also controversial for a long time, including the famous Beijing University on the Gold dms mistakes committed for some time and was unaware until he made a problem out of WA. . .

My understanding is this.

We note that low definition: low [x] x is a sub-tree of the smallest dfn. 

If you have visited, then it must be the ancestors of the current node.

If low, then it no longer meets the definition.

It does not affect the use of low pass dfn words. Because the low pass circle is passed back to the final strong root Unicom components, does not affect the value of its ancestors with low dfn transmitted to the other side, just as a low mark end transmission path. (Very emotional understanding).

Moreover, when considered with the low cut point, then put the whole Unicom strong component assimilated (low layers is passed, emotional understanding), then find cut points on the correctness of change. So low is incorrect.

Of course, because the topic map data more difficult to build, some problems with the data is not strong cause you can too low. Moreover, the impact is not big cut point for point with low shrinkage words.

 Emotional understanding finished, if you sensibility is not strong , I have no idea QWQ.

Spicy end.

To help you understand the words of a top bar.

Guess you like

Origin www.cnblogs.com/lbssxz/p/11234738.html