zoukankan      html  css  js  c++  java
  • HDU 1269 迷宫城堡(判断有向图强连通分量的个数,tarjan算法)

    迷宫城堡

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


    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
     
    分析:
    初识强连通分量题,采用tarjan算法出力强连通分量问题
    参考的是该大佬博客:
     
    题目分析:两两点之间互相可达,即判断该图的强连通分量是不是一个的问题
    code:
    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<string.h>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    int mon1[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
    int mon2[13]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
    int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
    
    int getval()
    {
        int ret(0);
        char c;
        while((c=getchar())==' '||c=='
    '||c=='
    ');
        ret=c-'0';
        while((c=getchar())!=' '&&c!='
    '&&c!='
    ')
            ret=ret*10+c-'0';
        return ret;
    }
    
    #define max_v 10005
    vector<int> vv[max_v];
    int vis[max_v];
    int dfn[max_v];
    int low[max_v];
    int ans[max_v];
    int n,m,cnt,sig;
    
    void init()
    {
        memset(low,0,sizeof(vis));
        memset(dfn,0,sizeof(dfn));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
            vv[i].clear();
    }
    
    void tarjan(int u)
    {
        vis[u]=1;
        dfn[u]=low[u]=cnt++;
        for(int i=0;i<vv[u].size();i++)
        {
            int v=vv[u][i];
            if(vis[v]==0)
                tarjan(v);
            if(vis[v]==1)
                low[u]=min(low[u],low[v]);
        }
        if(dfn[u]==low[u])
        {
            sig++;
        }
    }
    
    void slove()
    {
        cnt=1;
        sig=0;
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==0)
            {
                tarjan(i);
            }
        }
    }
    
    int main()
    {
        while(~scanf("%d %d",&n,&m))
        {
            if(n==0&&m==0)
                break;
            init();
            int x,y;
            for(int i=1;i<=m;i++)
            {
                scanf("%d %d",&x,&y);
                if(count(vv[x].begin(),vv[x].end(),y)==0)
                    vv[x].push_back(y);
            }
            slove();
            if(sig==1)
                printf("Yes
    ");
            else
                printf("No
    ");
        }
        return 0;
    }
    /*
    判断该图是不是强连通图,即强连通分量只有一个,就是它自己
    */
     
  • 相关阅读:
    微信小程序 简单控件
    #负分小组WEEK1#一个开头&小组介绍
    CountDownLatch使用场景及分析
    Markdown基础语法
    【转】awk的使用及字符串的操作
    【开篇有益】敢问路在何方,佛曰路就在脚下
    【EntityFramework 6.1.3】个人理解与问题记录(2)
    EETOOL简介
    VMware 安装失败 “Failed to create the requested registry key Key:installer Error:1021"
    vs2010调试时为什么会出现clr.dll与mscordacwks.dll版本不匹配?
  • 原文地址:https://www.cnblogs.com/yinbiao/p/9890163.html
Copyright © 2011-2022 走看看