zoukankan      html  css  js  c++  java
  • hdu 1269 强连通分量 模板题

    迷宫城堡

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 5322    Accepted Submission(s): 2373


    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
     
    Author
    Gardon
     
    Source
     
    Recommend
    lxj
     
    算法:即判断给定图是否是强连通图,即图含强连通分量数是否为1.
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    
    using namespace std;
    
    #define LL long long
    #define ULL unsigned long long
    #define UINT unsigned int
    #define MAX_INT 0x7fffffff
    #define MAX_LL 0x7fffffffffffffff
    #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
    
    #define MAXN 11111
    #define MAXM 100011
    
    struct edge{
        int u, v, nxt;
    }e[MAXM];
    int h[MAXN],dfn[MAXN],low[MAXN],cnt,id[MAXN];
    int n,m,cc;
    int vis[MAXN],ins[MAXN],s[MAXN],top;
    int tsp;
    
    inline void add(int u, int v){
        e[cc]=(edge){u, v, h[u]};
        h[u]=cc++;
    }
    
    void tarjan(int u){
        int v,i;
        s[top++]=u;
        ins[u]=vis[u]=1;
        low[u]=dfn[u]=++tsp;
    
        for(i=h[u]; i!=-1; i=e[i].nxt){
            v=e[i].v;
            if(!vis[v]) tarjan(v),low[u]=MIN(low[u], low[v]);
            else if(ins[v]) low[u]=MIN(low[u], dfn[v]);
        }
    
        if(low[u]==dfn[u]){
            ++cnt;
            do{
                v=s[--top];
                ins[v]=0;
                id[v]=cnt;
            }while(u!=v);
        }
    }
    
    int main(){
        while(scanf(" %d %d",&n,&m)==2 && (n||m)){
            int i,u,v,j;
            memset(h, -1, sizeof(h));       cc=0;
            for(i=0; i<m; i++){
                scanf(" %d %d",&u,&v);
                add(u, v);
            }
            memset(vis, 0, sizeof(vis));
            memset(ins, 0, sizeof(ins));
            top=tsp=cnt=0;
            for(i=1; i<=n; i++)
                if(!vis[i]) tarjan(i);
            for(j=id[1],i=2; i<=n; i++){
                if(j!=id[i]) break;
               // printf("i:%d %d
    ",i,id[i]);
            }
            if(i<=n) cout<<"No"<<endl;
            else cout<<"Yes"<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    算法导论 第一章
    20155312 2016-2017-2 《Java程序设计》第七周学习总结
    Visual Studio 2005 搭建Windows CE 6.0环境之准备
    C#在winform中调用系统控制台输出
    C# 目录(文件夹)复制实现
    关于加强数据库安全的一些实践
    运维小白部署网站踩坑全过程
    jQuery学习之二 jQuery选择器
    运维系列之二 Linux文件种类和扩展名
    运维系列之一 Linux的文件与目录权限解析
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3286225.html
Copyright © 2011-2022 走看看