• [targin]强联通分量+缩点


    在一个有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强联通。

    如果所有顶点都强联通,称G是一个强联通图。

    非强联通图有向图的极大强联通子图,称为强联通分量。

    深度优先搜索。

    DFN(i):节点i被搜索到的次序编号。

    LOW(i):i或i的子树能够追溯到的最早的节点的次序号。

    LOW I = min ( dfn i  , low j , dfn j)

    当DFN i = LOW i 以 i 为根的的子树上所有节点是一个强联通分量。

    时间复杂度:O(N+M)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include <bits/stdc++.h>
     6 using namespace std;
     7 typedef long long ll;
     8 const ll mod=998244353;
     9 const int N=1e5+100;
    10 const int maxn=1e6;
    11 const int MAXL=sqrt(1e14)+1;
    12 inline int read() {
    13     char c = getchar(); int x = 0, f = 1;
    14     while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    15     while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    16     return x * f;
    17 }
    18 int n,m;
    19 int Link[N],len=0,dfn[N],low[N],bok[N];
    20 int belong[N],id,bcnt;
    21 stack<int>s;
    22 struct node
    23 {
    24     int y,next;
    25 }e[2*N];
    26 void insert(int xx,int yy)
    27 {
    28     e[++len].next=Link[xx];
    29     Link[xx]=len;
    30     e[len].y=yy;
    31 }
    32 void targin(int x)
    33 {
    34     dfn[x]=low[x]=++id;
    35     s.push(x);
    36     bok[x]=1;
    37     for(int i=Link[x];i;i=e[i].next)
    38     {
    39         int v=e[i].y;
    40         if(!dfn[v])
    41         {
    42             targin(v);
    43             low[x]=min(low[x],low[v]);
    44         }
    45         else if(bok[v])
    46         {
    47             low[x]=min(low[x],dfn[v]);
    48         }
    49     }
    50     if(dfn[x]==low[x])
    51     {
    52         bcnt++;
    53         while(true)
    54         {
    55             int v=s.top();
    56             s.pop();
    57             bok[v]=0;
    58             belong[v]=bcnt;
    59             if(x==v)    break;
    60         }
    61     }
    62 
    63 }
    64 int solve()
    65 {
    66     n=read();   m=read();
    67     int xx,yy;
    68     for(int i=1;i<=m;i++)
    69     {
    70         xx=read();  yy=read();
    71         insert(xx,yy);
    72     }
    73     for(int i=1;i<=n;i++)
    74         if(!dfn[i])
    75             targin(i);
    76 
    77 
    78 }
    79 
    80 
    81 int main()
    82 {
    83     int T=1;
    84     scanf("%d",&T);
    85     //T=1;
    86     //cout<<tot<<endl;
    87     int tt=0;
    88     while(T--)
    89 
    90     {
    91         //if(n==0)    break;
    92         //printf("Case %d: ",++tt);
    93         solve();
    94     }
    95 
    96     return 0;
    97 
    98 }
    View Code

    缩点:

    for(int i=1;i<=n;i++)
        {
            for(int j=Link[i];j;j=e[i].next)
            {
                int v=e[j].y;
                if(belong[i]!=belong[v])
                    insert(belong[i],belong[v]);
            }
        }
    No matter how you feel, get up , dress up , show up ,and never give up.
  • 相关阅读:
    docker的基本操作
    docker和虚拟化技术的区别
    项目命名规则
    Javascript IE 内存释放
    关于ie的内存泄漏与javascript内存释放
    Java遍历HashMap并修改(remove)
    java 中类的加载顺序
    java类的加载以及初始化顺序 .
    JavaScript也谈内存优化
    JavaScript 的垃圾回收与内存泄露
  • 原文地址:https://www.cnblogs.com/Kaike/p/14490557.html
Copyright © 2020-2023  润新知