zoukankan      html  css  js  c++  java
  • HDU 1269 -- 迷宫城堡【有向图求SCC的数目 && 模板】

    迷宫城堡

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


    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
     
    有向图求SCC的裸题

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define maxn 10000 + 100
    #define maxm 100000 + 1000
    using namespace std;
    int n, m;
    struct node {
    	int u, v, next;
    };
    node edge[maxm];
    int head[maxn], cnt;
    int low[maxn], dfn[maxn];
    int dfs_clock;
    int Stack[maxn];
    bool Instack[maxn];
    int top;
    int Belong[maxn] , scc_clock;
    
    void init(){
    	cnt = 0;
    	memset(head, -1, sizeof(head));
    }
    
    void addedge(int u, int v){
    	edge[cnt] = {u, v, head[u]};
    	head[u] = cnt++;
    }
    
    void getmap(){
        while(m--){
            int a, b;
            scanf("%d%d", &a, &b);
            addedge(a, b);
        }
    }
    
    void tarjan(int u, int per){
        int v;
        low[u] = dfn[u] = ++dfs_clock;
        Stack[top++] = u;
        Instack[u] = true;
        int have = 1;
        for(int i = head[u]; i != -1; i = edge[i].next){
            v = edge[i].v;
            if(v == per && have){
                have = 0;
                continue;
            }
            if(!dfn[v]){
                tarjan(v, u);
                low[u] = min(low[v], low[u]);
            }
            else if(Instack[v]){
                low[u] = min(low[u], dfn[v]);
            }
        }
        if(dfn[u] == low[u]){
            scc_clock++;
            do{
                v = Stack[--top];
                Instack[v] = false;
                Belong[v] = scc_clock;
            }while(u != v);
        }
    }
    
    void find(){
        memset(low, 0, sizeof(low));
        memset(dfn, 0, sizeof(dfn));
        memset(Instack, false, sizeof(Instack));
        memset(Belong, 0, sizeof(Belong));
        dfs_clock = scc_clock = top = 0;
        for(int i = 1; i <= n; ++i){
            if(!dfn[i])
                tarjan(i, i);
        }
    }
    
    void solve(){
        if(scc_clock == 1)
            printf("Yes
    ");
        else
            printf("No
    ");
    }
    
    int main (){
    	while(scanf("%d%d", &n, &m), n || m){
            init();
            getmap();
            find();
            solve();
    	}
    	return 0;
    }
    


  • 相关阅读:
    操作系统设计与实现 读笔(2)
    操作系统设计与实现 读笔(1)
    C++历史及优点
    套接字Socket——TCP、UDP通信
    Unix环境_进程管理
    Unix环境_信号处理机制
    排序算法汇总
    TCP/IP体系结构
    数据库模式——三级模式两级映像
    杨辉三角形的递归实现
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7081899.html
Copyright © 2011-2022 走看看