zoukankan      html  css  js  c++  java
  • poj2762 强连通+拓扑序

    题意:有 n 个房间,不同房间之间有单向通道,问是否任意两个房间 A 、B 都可以从 A 到 B 或从 B 到 A(有一条有就可以)。

    在这题中,如果一些点是在同一个强连通分量中,那么这些点肯定能够相互到达,并且如果其他的点到达这里的任意一点,也就可以到达强连通分量中的所有点,所以首先需要对这题进行缩点。缩点之后图中就不存在环了,这时需要所有点间都至少有一条路,所以其实剩下了一条长链,并且是单向的,如果有双向的边就会被缩点,如果是数型图的话那么一个节点的多个子树就不能互相到达,所以一定是一条单向的长链,因此只要拓扑序判断就行,也可以对于这个图判段是否只有一点入度为1,一点出度为1,剩余点出入度都为1就行。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stack>
      4 #include<queue>
      5 using namespace std;
      6 
      7 const int maxn=1005;
      8 const int maxm=6005;
      9 
     10 int head[2][maxn],point[2][maxm],nxt[2][maxm],size[2];
     11 int n,t,scccnt;
     12 int id[maxn],stx[maxn],low[maxn],scc[maxn];
     13 stack<int>S;
     14 
     15 void init(){
     16     memset(head,-1,sizeof(head));
     17     size[0]=size[1]=0;
     18     memset(id,0,sizeof(head));
     19 }
     20 
     21 void add(int a,int b,int c=0){
     22     point[c][size[c]]=b;
     23     nxt[c][size[c]]=head[c][a];
     24     head[c][a]=size[c]++;
     25     if(c)id[b]++;
     26 }
     27 
     28 void dfs(int s){
     29     stx[s]=low[s]=++t;
     30     S.push(s);
     31     for(int i=head[0][s];~i;i=nxt[0][i]){
     32         int j=point[0][i];
     33         if(!stx[j]){
     34             dfs(j);
     35             low[s]=min(low[s],low[j]);
     36         }
     37         else if(!scc[j]){
     38             low[s]=min(low[s],stx[j]);
     39         }
     40     }
     41     if(low[s]==stx[s]){
     42         scccnt++;
     43         while(1){
     44             int u=S.top();S.pop();
     45             scc[u]=scccnt;
     46             if(s==u)break;
     47         }
     48     }
     49 }
     50 
     51 void setscc(){
     52     memset(stx,0,sizeof(stx));
     53     memset(scc,0,sizeof(scc));
     54     t=0;
     55     scccnt=0;
     56     for(int i=1;i<=n;++i)if(!stx[i])dfs(i);
     57     for(int i=1;i<=n;++i){
     58         for(int j=head[0][i];~j;j=nxt[0][j]){
     59             int k=point[0][j];
     60             if(scc[i]!=scc[k]){
     61                 add(scc[i],scc[k],1);
     62             }
     63         }
     64     }
     65 }
     66 
     67 bool topo(){
     68     queue<int>q;
     69     int cnt=0;
     70     for(int i=1;i<=scccnt;++i)if(!id[i])q.push(i);
     71     while(!q.empty()){
     72         int u=q.front();
     73         q.pop();
     74         if(!q.empty())return 0;
     75         cnt++;
     76         for(int i=head[1][u];~i;i=nxt[1][i]){
     77             int j=point[1][i];
     78             id[j]--;
     79             if(!id[j])q.push(j);
     80         }
     81     }
     82     if(cnt==scccnt)return 1;
     83     return 0;
     84 }
     85 
     86 int main(){
     87     int T;
     88     scanf("%d",&T);
     89     while(T--){
     90         int m;
     91         scanf("%d%d",&n,&m);
     92         init();
     93         while(m--){
     94             int a,b;
     95             scanf("%d%d",&a,&b);
     96             add(a,b);
     97         }
     98         setscc();
     99         if(topo())printf("Yes
    ");
    100         else printf("No
    ");
    101     }
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    leetcode--Lowest Common Ancestor of a Binary Search Tree
    bzoj3675【APIO2014】序列切割
    计算机网络之面试常考
    <html>
    TCP相关面试题总结
    Java多线程之Lock的使用
    原来Java中有两个ArrayList
    Java编程规范
    一些面试基本知识(Android篇一)
    _PyUnicodeUCS4_AsDefaultEncodedString
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4797734.html
Copyright © 2011-2022 走看看