Reachability (strongly connected component)



Topic description
Given a directed graph with 0 ≤ N ≤ 105 points and 0 ≤ M ≤ 105 edges,
Output a set of points as small as possible, so that any point can be reached from these points. If there are multiple such sets, output the sets with the smallest lexicographical order after sorting them in ascending order.
Enter description:
The first row contains two integers 1 ≤ n, m ≤ 105,
The next M lines, each line with two integers 1 ≤ u, v ≤ 105, indicate that there is a directed edge from point u to point v.
The data is guaranteed to have no double edges and self-loops.
Output description:
The first line outputs an integer z, representing the size of the point set as the answer;
The second line outputs z integers, sorted in ascending order, representing the set of points that are the answers.




After so many times, I can't send the code, let's see if I can send it this time.

This is a strong connected component problem encountered in an online competition yesterday.

Ideas:

There are no self-loops, but there may be loops.

Use the strongly connected component to remove the ring, and reduce each strongly connected component to the same component, and then find the number of points whose in-degree is 0 is the size of the point set. And when finding the strongly connected component, maintain the smallest point of each strongly connected component, and finally output the smallest point of the strongly connected component whose in-degree is 0, in ascending order. In fact, this is also a type of routine problem of strongly connected component problems, I remember that I seem to have encountered it before.



Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <stack>
#include <algorithm>
#define MA 100000+25
using namespace std;

vector<int>g[MA];
int dfn[MA],low[MA];
int sccno [MA], scc_cnt;
int n,m;
int min_sccno [MA], chu [MA];
int dfs_clock;
stack<int>s;
int in [MA];
void getmap()
{
    int u, v;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&u,&v);
        g[u].push_back(v);

    }
}

void dfs(int x)
{
    int v;
    low[x]=dfn[x]=++dfs_clock;
    s.push(x);
    for(int i=0;i<g[x].size();i++)
    {
        v=g[x][i];
        if(!dfn[v])
        {
            dfs(v);
            low[x]=min(low[x],low[v]);
        }
        else if(!sccno[v])
        {
            low[x]=min(low[x],dfn[v]);
        }
    }
    if(dfn[x]==low[x])
    {
        scc_cnt++;
        min_sccno [scc_cnt] = MA;
        for(;;)
        {
            v=s.top();
            s.pop();
            min_sccno [scc_cnt] = min (v, min_sccno [scc_cnt]);
            sccno[v]=scc_cnt;
            if(v==x)break;
        }
    }

}
void find_cut(int l,int r)
{
    memset(low,0,sizeof(low));
    memset(dfn,0,sizeof(dfn));
    memset(sccno,0,sizeof(sccno));
    scc_cnt=dfs_clock=0;

    for(int i=l;i<=r;i++)
    {
        if(!dfn[i]){dfs(i);}

    }
}
intmain()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(in,0,sizeof(in));
        memset (chu, 0, sizeof (chu));
        for(int i=0;i<n;i++)g[i].clear();
        getmap();
        find_cut(1,n);
        for(int i=1;i<=scc_cnt;i++)
        in[i]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<g[i].size();j++)
            {
                int v=g[i][j];
                if(sccno[v]!=sccno[i])
                {
                    and [sccno [v]] ++;
                }
            }
        }

        int ans=0;
        for(int i=1;i<=scc_cnt;i++)
        {
            if(!in[i])
            {
                chu [ans ++] = min_sccno [i];
            }
        }
        sort (chu, chu + ans);
        printf("%d\n",ans);
        for(int i=0;i<ans;i++)
        {
            if(i==0)printf("%d",chu[i]);
            else printf(" %d",chu[i]);
        }
        printf("\n");
    }
    return 0;
}







Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324600547&siteId=291194637