• 迷宫城堡 HDU


    为了训练小希的方向感,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

    题解:

    题目意思已经很明确了,就是让你去判断这个有向图是不是一个强连通图

    只是要保证两方面:

    1、只能有一个连通块

    2、这一个连通块中只有且仅有一个点x的low[x]==dfn[x]。因为在tarjan过程中如果要想变成一个强连通图,那么一定除了x的剩下所有点的low肯定要指向其他点

    代码:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<map>
      6 #include<math.h>
      7 #include<set>
      8 #include<queue>
      9 using namespace std;
     10 typedef long long ll;
     11 const int maxn=10005;
     12 const int mod=26;
     13 const int INF=0x3f3f3f3f;
     14 const int block=300;
     15 struct edge
     16 {
     17     int v,next;
     18 } e[100005];
     19 int dfn[maxn],low[maxn],stacks[maxn];
     20 int head[maxn],visit[maxn],cnt,tot,index;
     21 void add_edge(int x,int y)
     22 {
     23     e[cnt].v=y;
     24     e[cnt].next=head[x];
     25     head[x]=cnt++;
     26 }
     27 int tarjan(int x)
     28 {
     29     dfn[x]=low[x]=++tot;
     30     stacks[++index]=x;
     31     visit[x]=1;
     32     for(int i=head[x]; i!=-1; i=e[i].next)
     33     {
     34         if(!dfn[e[i].v])
     35         {
     36             tarjan(e[i].v);
     37             low[x]=min(low[x],low[e[i].v]);
     38         }
     39         else if(visit[e[i].v])
     40         {
     41             low[x]=min(low[x],dfn[e[i].v]);
     42         }
     43     }
     44     if(dfn[x]==low[x])
     45     {
     46         do{
     47             visit[stacks[index]]=0;
     48             index--;
     49         }while(x!=stacks[index+1]);
     50     }
     51 }
     52 int main()
     53 {
     54     int n,m;
     55     while(~scanf("%d%d",&n,&m))
     56     {
     57         if(!n && !m) break;
     58         cnt=0;
     59         for(int i=1;i<=n;++i)
     60         {
     61             head[i]=-1;
     62             visit[i]=0;
     63             dfn[i]=0;
     64             low[i]=0;
     65         }
     66         while(m--)
     67         {
     68             int x,y;
     69             scanf("%d%d",&x,&y);
     70             add_edge(x,y);
     71         }
     72         int flag=0;
     73         for(int i=1; i<=n; ++i)
     74         {
     75             if(!dfn[i])
     76             {
     77                 tarjan(i);
     78                 if(flag)
     79                 {
     80                     flag=2;
     81                     break;
     82                 }
     83                 else flag=1;
     84             }
     85             int ans=0;
     86             for(int i=1;i<=n;++i)
     87             {
     88                 if(dfn[i] && dfn[i]==low[i])
     89                 {
     90                     ans++;
     91                 }
     92                 if(ans>1)
     93                 {
     94                     flag=2;
     95                     break;
     96                 }
     97             }
     98         }
     99         if(flag==1)
    100         {
    101             printf("Yes
    ");
    102         }
    103         else printf("No
    ");
    104     }
    105     return 0;
    106 }
    View Code
  • 相关阅读:
    【MFC】对话框自带滚动条的使用
    【MFC】MFC DLEdit 设计属于自己的编辑框_鼠标悬停
    【MFC】MoveWindow();函数使用详解
    【MFC】SetWindowPos函数使用详解
    模板 key+1
    lazyload 分页加载
    缓慢显示隐藏
    js计算日期的前几天的日期
    判断子元素(or属性)是否存在
    动态加载的数据,hover效果
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11666602.html
Copyright © 2020-2023  润新知