zoukankan      html  css  js  c++  java
  • kosaraju算法

    这个是求一个图有几个强联通分量的算法

    先讲一下应该流程

    首先输入一个图G,创建一个反向的图GT

    图G

     对图进行dfs遍历,纪录每个点结束搜索的时间p[i]

    p[1]=2  p[2]=1  p[3]=5  p[4]=4  p[5]=3

    接下来对GT进行dfs搜索

    对图GT进行搜索的时候,先从之前纪录的时间最晚的点开始搜索

    就是从点3开始搜索

    若是3能在反向图中搜索到4意味着正向图中存在一条4->3的路   意思就是3和4互相抵达构成连通分量

    因为是时间从晚到早  所以不存在说从中间的某个点开始的情况

    意思就是不会出现下面的情况:

      对GT进行搜索

      先从2开始 搜索到1

      1之后没有点  纪录12是一个连通分量

      接下来345是一个连通分量

      但其实12不是一个连通分量

    所以我们从最晚的点开始搜索来避免这种情况

    接下来介绍为什么从最晚的点开始搜索能避免这种情况

    一个新图 只有1、2两个点

    1点是在2点之后结束搜索的

    那么有两种情况  第一种是 dfs(1)->dfs(2)->dfs(2)结束->dfs(1)结束

            第二种   dfs(2)->dfs(2)结束  dfs(1)->dfs(1)结束

    因为我们是从最后结束的点开始搜索   

    即对反向图从1开始搜索

    那么假设反向图中1能搜索到2   那么说明原图的2能到达1

    既然原图的2能够到达1   那么就不会出现dfs(2)->dfs(2)结束  dfs(1)->dfs(1)结束这种情况 

    否则为什么dfs(2)不进入dfs(1)呢

    所以原图的1能够到达2

    然后就是GT图   1能搜索到2   那么原图2能搜索到1   说明1和2连通

    结论:按原图dfs结束时间对方向图进行搜索,搜索到的点都能够构成连通分量

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int maxn = 2005;
    vector<int> G[maxn],G2[maxn];
    int p[maxn];
    bool q[maxn];
    int n;
    int cnt = 1;
    void dfs(int u);
    void dfs2(int u);
    int main()
    {
        int i,j;
        char str[2005];
        scanf("%d",&n);
        for(i=1;i<=n;++i)
        {
            scanf("%s",str+1);
            for(j=1;j<=n;++j)
            {
                if(str[j] == '1')
                {
                    G[i].push_back(j);
                    G2[j].push_back(i);
                }
            }
        }
        memset(q, 0, sizeof(q));
        for(i=1;i<=n;++i)
            dfs(i);
        int sum = 0;
        memset(q, 0, sizeof(q));
        for(i=n;i>=1;--i)
        {
            if(q[p[i]] == false)
            {
                sum ++ ; dfs2(p[i]);
            }
        }
        cout << sum << endl;
        return 0;
    }
    void dfs(int u)
    {
        q[u] = true;
        for(int i=0;i<G[u].size();++i)
        {
            if(q[G[u][i]] == false)
            {
                dfs(G[u][i]);
            }
        }
        p[cnt++] = u;
    }
    void dfs2(int u)
    {
        int i;
        q[u] = true;
        for(i=0;i<G2[u].size();++i)
        {
            if(q[G2[u][i]] == false)
            {
                dfs2(G2[u][i]);
            }
        }
    }
  • 相关阅读:
    软件工程概论(课堂作业01)
    java小程序(课堂作业06)
    动手动脑(课堂作业06)
    动手动脑(课堂作业05)
    java小程序(课堂作业04)
    动手动脑(课堂作业04)
    java小程序(课堂作业03)
    动手动脑(课堂作业03)
    动手动脑(课堂作业02)
    Codeforces 178B1-B3 Greedy Merchants
  • 原文地址:https://www.cnblogs.com/mltang/p/9022696.html
Copyright © 2011-2022 走看看