zoukankan      html  css  js  c++  java
  • 【图论补完计划】poj 2762 (强连通分量 kosaraju)

    Going from u to v or from v to u?
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 17479   Accepted: 4694

    Description

    In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn't know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

    Input

    The first line contains a single integer T, the number of test cases. And followed T cases.

    The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.

    Output

    The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.

    Sample Input

    1
    3 3
    1 2
    2 3
    3 1
    

    Sample Output

    Yes


    题意
    询问一个有向图的任意两点s,t,是否存在s可达t或t可达s,如果都存在输出Yes,否则输出No。

    做法

    scc拆点,建图,记录入度,如果存在两个及两个以上的入度为0的点则无解,找到入度为0的点作为根进行dfs,因为是一条链,如果出现分叉点(新图的点的邻接边数目>=2)则无解。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <algorithm>
      6 
      7 using namespace std;
      8 
      9 const int maxn=1005;
     10 
     11 vector<int> G[maxn];
     12 vector<int> rG[maxn];
     13 vector<int> nG[maxn];
     14 vector<int> vs;
     15 
     16 int n,m;
     17 
     18 int cmp[maxn],d[maxn];
     19 bool used[maxn],tag;
     20 
     21 inline int read(){
     22     int x=0,f=1;char ch=getchar();
     23     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
     24     while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
     25     return x*f;
     26 }
     27 
     28 void init(){
     29     for(int i=0;i<maxn;i++){
     30         G[i].clear();rG[i].clear();nG[i].clear();
     31         d[i]=0;cmp[i]=0;
     32     }
     33     tag=false;
     34 }
     35 
     36 void add_edge(int s,int t){
     37     G[s].push_back(t);
     38     rG[t].push_back(s);
     39 }
     40 
     41 void dfs(int s){
     42     used[s]=true;
     43     for(int i=0;i<G[s].size();i++){
     44         if(!used[G[s][i]]) dfs(G[s][i]);
     45     }
     46     vs.push_back(s);
     47 }
     48 
     49 void rdfs(int s,int k){
     50     used[s]=true;
     51     cmp[s]=k;
     52     for(int i=0;i<rG[s].size();i++){
     53         if(!used[rG[s][i]]) rdfs(rG[s][i],k);
     54     }
     55 }
     56 
     57 void ndfs(int root){
     58     if(nG[root].size()>1){
     59         tag=true;
     60         return;
     61     }
     62     if(nG[root].size()==0) return;
     63     ndfs(nG[root][0]);
     64 }
     65 
     66 int scc(){
     67     memset(used,0,sizeof(used));
     68     vs.clear();
     69     for(int i=1;i<=n;i++){
     70         if(!used[i]) dfs(i);
     71     }
     72     memset(used,0,sizeof(used));
     73     int k=0;
     74     for(int i=vs.size()-1;i>=0;i--){
     75         if(!used[vs[i]]) rdfs(vs[i],++k);
     76     }
     77     return k;
     78 }
     79 
     80 int main(){
     81     int T;
     82     T=read();
     83     while(T--){
     84         init();
     85         n=read();m=read();
     86         for(int i=0;i<m;i++){
     87             int s,t;
     88             s=read();t=read();
     89             add_edge(s,t);
     90         }
     91         int k=scc();
     92         for(int i=1;i<=n;i++){
     93             for(int j=0;j<G[i].size();j++){
     94                 int v=G[i][j];
     95                 if(cmp[i]==cmp[v]) continue;
     96                 nG[cmp[i]].push_back(cmp[v]);
     97                 d[cmp[v]]++;
     98             }
     99         }
    100         int root=0;bool flag=false;
    101         for(int i=1;i<=k;i++){
    102             if(d[i]==0){
    103                 if(root){
    104                     flag=true;
    105                     break;
    106                 }
    107                 root=i;
    108             }
    109         }
    110         if(flag){
    111             printf("No
    ");
    112         }
    113         else{
    114             ndfs(root);
    115             if(!tag) printf("Yes
    ");
    116             else printf("No
    ");
    117         }
    118     }
    119     return 0;
    120 }
    
    
    
     
  • 相关阅读:
    Hibernate之必须导入jar包
    浏览器兼容性问题
    CSS中的浮动清除
    CSS的三种手段让元素脱离标准本文档流——浮动、绝对定位、固定定位
    块级元素和行内元素
    网页设计前端——盒子模型
    CSS的继承性和层叠性
    网站前端设计——选择器
    网站中图片的相对路径与绝对路径
    网站隐藏文件夹
  • 原文地址:https://www.cnblogs.com/hymscott/p/6527648.html
Copyright © 2011-2022 走看看