hdu1269迷宫城堡(判断有向图是否是一个强连通图)

/*
          题意: 给你一个图,求这个有向图示否是一个强连通图(每两个节点都是可以相互到达的)!
          思路1:按正向边dfs一遍,将经过的节点计数,如果记录的节点的个数小于n,那么就说明图按照正向边就不是连同的,所以就不是强连通图!
                然后按照反向边再进行另一个dfs,同样对经过的节点的个数进行计数,如果个数==n则说明正向遍历和反响遍历都是连通的!那么整个图就是强连通的图!

          思路2:直接套用tarjan算法,求出每一个节点所对应的缩点的值, 如果缩点的个数==1,那么证明就会只有一个强连通分量!也就是强连通图

          思路3:多次次调用tarjan算法,判断low[u]==pre[u]&&u==1, 如果不满足说明改图有多个缩点,那就不是强连通图!下图说明一下....

     */
  //思路一:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 10005
using namespace std;

vector<int>uv[N];
vector<int>vu[N];

int vis[N];

int cnt;

int n, m;

void dfs1(int u){
    vis[u]=1;
    ++cnt;
    int len=uv[u].size();
    for(int i=0; i<len; ++i){
        int v=uv[u][i];
        if(!vis[v])
           dfs1(v);
    }
}

void dfs2(int v){
    vis[v]=1;
    ++cnt;
    int len=vu[v].size();
    for(int i=0; i<len; ++i){
        int u=vu[v][i];
        if(!vis[u])
           dfs2(u);
    }
}

int main(){
   while( scanf("%d%d", &n, &m) && (n||m) ){
       memset(vis, 0, sizeof(vis));
       for(int i=1; i<=n; ++i){
           uv[i].clear();
           vu[i].clear();
       }
       while(m--){
           int u, v;
           scanf("%d%d", &u, &v);
           uv[u].push_back(v);
           vu[v].push_back(u);
       }
       cnt=0;
       dfs1(1);

       if(cnt==n){
          memset(vis, 0, sizeof(vis));
          cnt=0;
          dfs2(1);
          if(cnt!=n)
             printf("No\n");
          else printf("Yes\n");
       }
       else printf("No\n");

   }
   return 0;
}

 //思路二:
 #include<iostream>
 #include<cstring>
 #include<cstdio>
 #include<algorithm>
 #include<vector>
 #include<stack>
 #define N 10005
 using namespace std;

 vector<int>g[N];
 stack<int>s;
 int pre[N], low[N];
 int scc[N];
 int scc_cnt;
 int dfs_clock;

 void tarjans(int u){
     pre[u]=low[u]=++dfs_clock;
     s.push(u);
     int len=g[u].size();
     for(int i=0; i<len; ++i){
        int v=g[u][i];
        if(pre[u]>pre[v]){
            if(!pre[v]){
                tarjans(v);
                low[u]=min(low[v], low[u]);
             }
            else
                low[u]=min(pre[v], low[u]);
         }
     }

     if(low[u]==pre[u]){
         ++scc_cnt;
         while(1){
             int x=s.top();
             s.pop();
             scc[x]=scc_cnt;
             if(x==u) break;
         }
     }
 }

 int n, m;
 int main(){
     while(scanf("%d%d", &n, &m) && (n||m)){
         while(m--){
            int u, v;
            scanf("%d%d", &u, &v);
            g[u].push_back(v);
         }
         dfs_clock=0;
         scc_cnt=0;
         for(int i=1; i<=n; ++i)
           if(!scc[i])
              tarjans(i);
         int i;
         for(i=2; i<=n; ++i)
             if(scc[i]!=scc[1]){
                 printf("No\n");
                 break;
             }
         if(i>n)   printf("Yes\n");
         memset(pre, 0, sizeof(pre));
         memset(low, 0, sizeof(low));
         memset(scc, 0, sizeof(scc));
         for(i=1; i<=n; ++i)
            g[i].clear();
     }
     return 0;
}

 //思路三:
 #include<iostream>
 #include<cstring>
 #include<cstdio>
 #include<algorithm>
 #include<vector>
 #define N 10005
 using namespace std;

 vector<int>g[N];
 bool flag;
 int pre[N], low[N];
 int dfs_clock;

 void tarjans(int u){
     pre[u]=low[u]=++dfs_clock;
     int len=g[u].size();
     for(int i=0; i<len; ++i){
        int v=g[u][i];
        if(!flag) return ;
        if(pre[u]>pre[v]){
            if(!pre[v]){
                tarjans(v);
                low[u]=min(low[v], low[u]);
             }
            else
                low[u]=min(pre[v], low[u]);
         }
     }

     if(low[u]==pre[u] && u!=1)
         flag=false;
 }

 int n, m;
 int main(){
     while(scanf("%d%d", &n, &m) && (n||m)){
         while(m--){
            int u, v;
            scanf("%d%d", &u, &v);
            g[u].push_back(v);
         }
         dfs_clock=0;
         flag=true;
         for(int i=1; i<=n; ++i)
           if(!pre[i]){
              if(!flag) break;
              tarjans(i);
           }

         if(!flag)  printf("No\n");
         else       printf("Yes\n");
         memset(pre, 0, sizeof(pre));
         memset(low, 0, sizeof(low));
         for(int i=1; i<=n; ++i)
            g[i].clear();
     }
     return 0;
}
时间: 2024-08-30 02:40:31

hdu1269迷宫城堡(判断有向图是否是一个强连通图)的相关文章

矩阵-如何判断有向图中是否存在环路?

问题描述 如何判断有向图中是否存在环路? 如何判断有向图中是否存在环路?输入的格式是有向图的边,而不是邻接矩阵,又该怎么做呢?用Java或者C#可以实现么? 解决方案 http://blog.sina.com.cn/s/blog_4513dde60100o6uk.html 这种有向图的表示法使用字典(Dictionary)和列表(List).例如一个如下的有向图 这里往下看 解决方案二: 你可以把有向图的边转换为字典或者邻接矩阵

判断的条件是一个字符串的长度

条件|字符串 2004-10-810:49:42青 好好利用时间(f)wingc@SQL也不简单啊吴聪,请教一下sql中,如果判断的条件是一个字符串的长度,比如column1字段的长度是3,如"001"就能入选.这样的条件怎么写??我google it first了2004-10-810:50:37(f)wingc@SQL也不简单啊青 好好利用时间SQL Server中用len(字段名) = 3,试过没?2004-10-810:50:55青 好好利用时间(f)wingc@SQL也不简单

php判断字符串在另一个字符串位置的方法

 这篇文章主要介绍了php判断字符串在另一个字符串位置的方法,需要的朋友可以参考下    代码如下: $email='user@exe.com';        //定义字符串 $result=strstr($email,'@');         //返回子字符串 echo $result;      strstr()函数搜索一个字符串在另一个字符串中的第一次出现.   该函数返回字符串的其余部分(从匹配点).如果未找到所搜索的字符串,则返回 false.   语法      代码如下:  

c中怎么编写代码实现:判断文件中的一个字符串是拼写错误还是根本不存在!!

问题描述 c中怎么编写代码实现:判断文件中的一个字符串是拼写错误还是根本不存在!! 代码怎么编啊.提供思路也可以,,求各位大神指点,,万分感谢!! 解决方案 不是两个if else 么,if. 不为空,if.equal("xxoo") 解决方案二: 这个,你需要用字典,去判断,然后还需要词法分析. 解决方案三: 你要定义一下什么是拼写错误,什么属于根本不存在.比如说,如果字符数一致,但是有一个字符与字典里的字符串不一致,这样就算是拼写错误. 或者说只要与字典里的字符串不一致都算拼写错误

如何判断easyui中某一个window是否已经show

问题描述 如何判断easyui中某一个window是否已经show 我需要判断一下 如果window是否正显示着(show出) 如果是 就关闭我的window 显示的是我的div的内容 不是跳转的新页面内容 解决方案 默认好像没办法,你可以注册回调函数 记录下状态$('#w').window({"onOpen":function(){alert(1)}});http://blog.sina.com.cn/s/blog_5d225a7b0100mm1u.html解决方案二:$('#lis

如何判断Unix系统的一个库文件是32位还是64位的

如何判断Unix系统的一个库文件是32位还是64位的 某些时候,我们需要知道操作系统的位数,或者配置插件的时候需要知道主程序的位数(例如配置apache插件的时候需要知道apache的位数以便配置相应的插件),最简单的办法就是执行file命令,如: file 命令 Linux: # file libnss1_files-2.2.4.so  libnss1_files-2.2.4.so: ELF 32-bit LSB shared object, Intel 80386, version 1, n

请问如何判断并取出另外一个数据库文档中RTF域的内容????

问题描述 数据库A为文档,数据库B为文档附件在数据库A中编写代码,需要取出在数据库B中对应文档的附件内容(RTF域),请教该如何实现??目前遇到的问题是:如何判断数据库B中对应文档的RTF附件域的内容是否为空,为空时就不用取出其内容,否则取出其内容看到网上有一段判断RTF域是否为空的代码FunctionIsRTFNull(rtfieldAsString)AsIntegerOnErrorGotoErrhandleDimworkspaceAsNewNotesUIWorkspaceDimuidocAs

php判断字符串在另一个字符串位置的方法_php实例

复制代码 代码如下: $email='user@exe.com';        //定义字符串$result=strstr($email,'@');         //返回子字符串echo $result; strstr()函数搜索一个字符串在另一个字符串中的第一次出现. 该函数返回字符串的其余部分(从匹配点).如果未找到所搜索的字符串,则返回 false. 语法 复制代码 代码如下: strstr(string,search)输出结果"@exe.com"

php 判断字符串在另一个字符串中位置

$email='user@example.com';        //定义字符串 $result=strstr($email,'@');         //返回子字符串 echo $result;  /* strstr() 函数搜索一个字符串在另一个字符串中的第一次出现. 该函数返回字符串的其余部分(从匹配点).如果未找到所搜索的字符串,则返回 false. 语法 strstr(string,search) */          //输出结果"@example.com"