• Semiconnected--强连通缩点


    1451: Semiconnected

    时间限制: 1 Sec  内存限制: 32 MB
    提交: 79  解决: 20

    题目描述

    For a directed graph G = (V, E), if for all pairs of nodes u,v, u can always reach v or v can always reach u , then we call this a Semiconnected graph. Now you are given a directed graph, you should tell us whether it is a Semiconnected graph. If it is, output “yes”, or else“no”.

    输入

    There are several test cases, for each test case, there are two integers in the first line, n and m n(n<=10000) ,m(m<=50000) , means that there are n nodes and m edges in this graph. The nodes are numbered from 1 to n. Then m lines each with two integers u and v means there is an edge from u to v.

    输出

    For each test case, output “yes” if it is a Semiconnected graph, or else “no” instead.

    样例输入

    4 3
    1 2
    2 3
    3 4
    4 3
    1 2
    2 3
    4 3

    样例输出

    yes
    no

    题意:给你一个有向图,若从图中任意两个点u,v。都有从u到v的路径,或者从v到u的路径,则该图为半连通的,是则输出yes,不是则输出no

    思路:若该图符合以上情况,

            1:入度为0的点多于一个,不符合。

            2:对该图进行缩点后,若为半连通图,则当前的图为一条直线,统计新图中入度,出度为0的点是不是都只有一个即可。

    代码如下:

    #include "stdio.h"  //强连通缩点后,判断新图中入度为0,出度为0的点是否都只有一个
    #include "string.h"
    #include "vector"
    #include "stack"
    using namespace std;
    
    #define N 10005
    #define M 50005
    
    struct node
    {
        int x,y;
        int next;
    }edge[M];
    int idx,head[N];
    void Init(){ idx=0; memset(head,-1,sizeof(head)); }
    void Add(int x,int y)
    {
        edge[idx].x=x; edge[idx].y=y;
        edge[idx].next=head[x]; head[x]=idx++;
    }
    
    int n;
    int dfs_clock;
    bool mark[N];
    int scc_cnt;
    int belong[N];
    stack<int> q;
    int num[N];
    int low[N],dfn[N];
    int MIN(int a,int b) { return a<b?a:b; }
    
    void DFS(int x)
    {
        int i,y;
        q.push(x);
        mark[x] = true;
        low[x] = dfn[x] = ++dfs_clock;
        for(i=head[x]; i!=-1; i=edge[i].next)
        {
            y=edge[i].y;
            if(!dfn[y])
            {
                DFS(y);
                low[x] = MIN(low[x],low[y]);
            }
            else if(mark[y])
                low[x] = MIN(dfn[y],low[x]);
        }
        if(low[x]==dfn[x])
        {
            int temp;
            scc_cnt++;
            while(1)
            {
                temp = q.top();
                q.pop();
                belong[temp] = scc_cnt;
                num[scc_cnt]++;
                mark[temp] = false;
                if(temp==x) break;
            }
        }
    }
    
    int ru_du[N],chu_du[N];
    
    void Solve(int id)
    {
        int i;
        int x,y;
        dfs_clock = scc_cnt = 0;
        memset(dfn,0,sizeof(dfn));
        memset(num,0,sizeof(num));
        memset(belong,0,sizeof(belong));
        memset(mark,false,sizeof(mark));
        DFS(id);
        for(i=1; i<=n; ++i)
        {
            if(!dfn[i])
                DFS(i);
        }
        memset(ru_du,0,sizeof(ru_du));
        memset(chu_du,0,sizeof(chu_du));
        for(i=0; i<idx; ++i)
        {
            x = edge[i].x;
            y = edge[i].y;
            if(belong[x]!=belong[y])
            {
                chu_du[belong[x]]++;
                ru_du[belong[y]]++;
            }
        }
        int ru_0=0;
        int chu_0=0;
        for(i=1; i<=scc_cnt; ++i)
        {
            if(ru_du[i]==0)
                ru_0++;
            if(chu_du[i]==0)
                chu_0++;
        }
        if(ru_0==1 && chu_0==1)
            printf("yes
    ");
        else
            printf("no
    ");
    }
    
    int ru[N],chu[N];
    
    int main()
    {
        int i,m;
        int x,y;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            Init();
            memset(ru,0,sizeof(ru));
            memset(chu,0,sizeof(chu));
            while(m--)
            {
                scanf("%d%d",&x,&y);
                Add(x,y);
                chu[x]++;
                ru[y]++;
            }
            int ans=0,id=1;
            for(i=1; i<=n; ++i)
            {
                if(ru[i]==0)
                {
                    ans++;
                    id=i;
                }
            }
            if(ans>1) { printf("no
    "); continue; }
            Solve(id);
        }
        return 0;
    }
    
    
    






  • 相关阅读:
    【译文】不是所有的 bug 都值得修复的
    11月第5周业务风控关注|重磅!瓜子二手车“遥遥领先”被罚天价1250万
    AutoCAD .NET二次开发(四)
    AutoCAD .NET二次开发(三)
    ArcGIS10.2下调试10.1的程序
    再遇1402,注册表权限问题
    ArcGIS Add-in——自动保存编辑
    只打开一个子窗体
    获取编辑器两种方法
    Adobe Acrobat Pro 11安装激活
  • 原文地址:https://www.cnblogs.com/ruo-yu/p/4411962.html
Copyright © 2020-2023  润新知