zoukankan      html  css  js  c++  java
  • 迷宫城堡(有向图的强联通分量)

    迷宫城堡
    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 19906    Accepted Submission(s): 8688






    Problem Description


    为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。




     




    Input


    输入包含多组数据,输入的第一行有两个数:N和M,接下来的M行每行有两个数a和b,表示了一条通道可以从A房间来到B房间。文件最后以两个0结束。




     




    Output


    对于输入的每组数据,如果任意两个房间都是相互连接的,输出"Yes",否则输出"No"。




     




    Sample Input


    3 3
    1 2
    2 3
    3 1
    3 3
    1 2
    2 3
    3 2
    0 0




     




    Sample Output


    Yes
    No

    强连通(strongly connected): 在一个有向图G里,设两个点 a b 发现,由a有一条路可以走到b,由b又有一条路可以走到a,我们就叫这两个顶点(a,b)强连通。

    强连通图: 如果 在一个有向图G中,每两个点都强连通,我们就叫这个图,强连通图。

    强连通分量strongly connected components):在一个有向图G中,有一个子图,这个子图每2个点都满足强连通,我们就叫这个子图叫做 强连通分量 [分量::把一个向量分解成几个方向的向量的和,那些方向上的向量就叫做该向量(未分解前的向量)的分量]

    Tarjan:


    #include<map>
    #include<stack>
    #include<queue>
    #include<math.h>
    #include<vector>
    #include<string>
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #define maxn 10005
    #define maxm 100005
    #define ll long long
    #define inf 0x3f3f3f
    using namespace std;
    struct edge{
        int to,next;
    }edge[maxm];
    int head[maxn],tot;
    int low[maxn],dfn[maxn],stac[maxn],belong[maxn];
    int index,top;
    int scc;
    bool instack[maxn];
    int num[maxn];
    void addedge(int u,int v){
        edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
    }
    void Tarjan(int u){
        int v;
        low[u]=dfn[u]=++index;
        stac[top++]=u;
        instack[u]=true;
        for(int i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].to;
            if(!dfn[v]){
                Tarjan(v);
                if(low[u]>low[v])low[u]=low[v];
            }
            else if(instack[v]&&low[u]>dfn[v])
                low[u]=dfn[v];
        }if(low[u]==dfn[u]){
            scc++;
            do{
                v=stac[--top];
                instack[v]=false;
                belong[v]=scc;
                num[scc]++;
            }while(v!=u);
        }
    }
    void solve(int n){
        memset(dfn,0,sizeof(dfn));
        memset(instack,false,sizeof(instack));
        memset(num,0,sizeof(num));
        index=scc=top=0;
        for(int i=1;i<=n;i++){
            if(!dfn[i])Tarjan(i);
        }
    }
    void init(){
        tot=0;
        memset(head,-1,sizeof(head));
    }
    int main(){
        int n,m;
        while(~scanf("%d%d",&n,&m)){
            if(n==0&&m==0)break;
            init();
            for(int i=0;i<m;i++){
                int a,b;scanf("%d%d",&a,&b);
                addedge(a,b);
            }
            solve(n);
            if(scc==1)printf("Yes
    ");
            else printf("No
    ");
        }
    }
    




     

  • 相关阅读:
    导航守卫
    asnyc
    扩展运算符 ···
    模版字符串
    iterator迭代器
    箭头函数
    解构
    变量let const
    vueUI可视化
    python图像特征提取
  • 原文地址:https://www.cnblogs.com/da-mei/p/9053251.html
Copyright © 2011-2022 走看看