zoukankan      html  css  js  c++  java
  • hdu1269迷宫城堡(判断有向图是否是一个强连通图)

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

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

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


    */
    //思路一:
    2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<vector> 7 #define N 10005 8 using namespace std; 9 10 vector<int>uv[N]; 11 vector<int>vu[N]; 12 13 int vis[N]; 14 15 int cnt; 16 17 int n, m; 18 19 void dfs1(int u){ 20 vis[u]=1; 21 ++cnt; 22 int len=uv[u].size(); 23 for(int i=0; i<len; ++i){ 24 int v=uv[u][i]; 25 if(!vis[v]) 26 dfs1(v); 27 } 28 } 29 30 31 void dfs2(int v){ 32 vis[v]=1; 33 ++cnt; 34 int len=vu[v].size(); 35 for(int i=0; i<len; ++i){ 36 int u=vu[v][i]; 37 if(!vis[u]) 38 dfs2(u); 39 } 40 } 41 42 int main(){ 43 while( scanf("%d%d", &n, &m) && (n||m) ){ 44 memset(vis, 0, sizeof(vis)); 45 for(int i=1; i<=n; ++i){ 46 uv[i].clear(); 47 vu[i].clear(); 48 } 49 while(m--){ 50 int u, v; 51 scanf("%d%d", &u, &v); 52 uv[u].push_back(v); 53 vu[v].push_back(u); 54 } 55 cnt=0; 56 dfs1(1); 57 58 if(cnt==n){ 59 memset(vis, 0, sizeof(vis)); 60 cnt=0; 61 dfs2(1); 62 if(cnt!=n) 63 printf("No "); 64 else printf("Yes "); 65 } 66 else printf("No "); 67 68 } 69 return 0; 70 } 71
     //思路二:
    #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 "); break; } if(i>n) printf("Yes "); 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; }

     //思路三:
    1
    #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<vector> 6 #define N 10005 7 using namespace std; 8 9 vector<int>g[N]; 10 bool flag; 11 int pre[N], low[N]; 12 int dfs_clock; 13 14 void tarjans(int u){ 15 pre[u]=low[u]=++dfs_clock; 16 int len=g[u].size(); 17 for(int i=0; i<len; ++i){ 18 int v=g[u][i]; 19 if(!flag) return ; 20 if(pre[u]>pre[v]){ 21 if(!pre[v]){ 22 tarjans(v); 23 low[u]=min(low[v], low[u]); 24 } 25 else 26 low[u]=min(pre[v], low[u]); 27 } 28 } 29 30 if(low[u]==pre[u] && u!=1) 31 flag=false; 32 } 33 34 int n, m; 35 int main(){ 36 while(scanf("%d%d", &n, &m) && (n||m)){ 37 while(m--){ 38 int u, v; 39 scanf("%d%d", &u, &v); 40 g[u].push_back(v); 41 } 42 dfs_clock=0; 43 flag=true; 44 for(int i=1; i<=n; ++i) 45 if(!pre[i]){ 46 if(!flag) break; 47 tarjans(i); 48 } 49 50 if(!flag) printf("No "); 51 else printf("Yes "); 52 memset(pre, 0, sizeof(pre)); 53 memset(low, 0, sizeof(low)); 54 for(int i=1; i<=n; ++i) 55 g[i].clear(); 56 } 57 return 0; 58 } 59
    
    
    
    
    
  • 相关阅读:
    从书上学的东西(顺带总结一发)
    网上讲的好的知识点汇总
    土地征用题解(兼斜率优化详解)
    Blocks题解(区间dp)
    高精度模板汇总
    动态规划总结
    异或序列(题解)(莫队)
    小Z的袜子(题解)(莫队)
    小B的询问(题解)(莫队)
    凸包模板——Graham扫描法
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/3928056.html
Copyright © 2011-2022 走看看