zoukankan      html  css  js  c++  java
  • tarjan求强连通分量模板

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <string>
     7 #include <string.h>
     8 #define gc getchar()
     9 using namespace std;
    10 int n,m;
    11 int g[233333]={};
    12 int DFN[233333];
    13 int Low[233333];
    14 int cnt=0;
    15 int stack[233333];
    16 bool v[233333]={};
    17 bool instack[233333]={};
    18 int top=0;
    19 int Index=0;
    20 struct node
    21 {
    22     int to,next;
    23 }e[466666];
    24 int t[233333];
    25 int ax=0;
    26 void addedge(int x,int y)
    27 {
    28     e[++cnt].next=g[x];
    29     g[x]=cnt;
    30     e[cnt].to=y;
    31 }
    32 int read()
    33 {
    34     int xxxx=0,fuh=1;char ch=gc;
    35     while(!isdigit(ch)){
    36         if(ch=='-')fuh=-1;
    37         ch=gc;
    38     }
    39     while(isdigit(ch)){
    40         xxxx=(xxxx<<3)+(xxxx<<1)+ch-'0';ch=gc;
    41     }
    42     return xxxx*fuh;
    43 }
    44 void tarjan(int u) 
    45 {
    46     int i;
    47     DFN[u]=Low[u]=++Index;     // 为节点u设定次序编号和Low初值
    48     stack[++top]=u;    
    49     instack[u]=1;               // 将节点u压入栈中
    50     for (i=g[u];i;i=e[i].next)   // 枚举每一条边
    51       {            
    52         if (!DFN[e[i].to])      // 如果节点v未被访问过
    53           {    
    54              tarjan(e[i].to);            // 继续向下找
    55              Low[u]=min(Low[u],Low[e[i].to]);
    56           }
    57         else 
    58           if (instack[e[i].to])            // 如果节点v还在栈内
    59             Low[u]=min(Low[u],DFN[e[i].to]);
    60     }
    61     if(DFN[u]==Low[u])
    62         while(stack[top+1]!=u)
    63           {
    64             ++t[u];
    65             instack[stack[top--]]=false;
    66         }
    67 }
    68 int main()
    69 {
    70     n=read();m=read();int t1,t2;
    71     for (int i=1;i<=m;i++)
    72       {
    73           t1=read();
    74         t2=read();
    75         addedge(t1,t2);
    76       }
    77   
    78     for(int i=1;i<=n;i++) 
    79       if(!DFN[i])  tarjan(i);
    80     cout<<*max_element(t+1,t+n+1);
    81     return 0;
    82 }
    View Code
    1. if (DFN[u] == Low[u])                      // 如果节点u是强连通分量的根  
    2.         repeat  
    3.             v = S.pop                  // 将v退栈,为该强连通分量中一个顶点  
    4.             print v  
    5.         until (u== v)
    Rem is my wife!(。・`ω´・)
  • 相关阅读:
    最长公共子序列解题报告
    数列操作问题
    数字金字塔解题报告
    Formiko总结整数十进制转换二进制原理
    程序设计竞赛问题类型
    vue 的生命周期
    小程序 瀑布流布局(图-视频)
    JavaScript语言里判断一个整数是偶数还是奇数,并输出判断结果
    JavaScript语言里判断一个整数,属于哪个范围:大于0;小于0;等于0
    test
  • 原文地址:https://www.cnblogs.com/yz12138/p/5931774.html
Copyright © 2011-2022 走看看