• [poj2762] Going from u to v or from v to u?(Kosaraju缩点+拓排)


    转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud
     
     
    Going from u to v or from v to u?
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 14778   Accepted: 3911

    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

    题意:给一个图,问是否为单向连通。

    Kosaraju+缩点,然后拓扑序搞一下,若只有一条没有分支的链,则Yes,否则No

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <vector>
      5 using namespace std;
      6 const int maxn=1010;
      7 vector<int>G[maxn];
      8 vector<int>rG[maxn];
      9 vector<int>vs;
     10 int vis[maxn];
     11 int cmp[maxn];
     12 int last[maxn];
     13 int deg[maxn];
     14 int next[maxn];
     15 int V;
     16 vector<int>vc[maxn];
     17 void add_edge(int u,int v)
     18 {
     19     G[u].push_back(v);
     20     rG[v].push_back(u);
     21 }
     22 void init(int n)
     23 {
     24     for(int i=0;i<n;i++)
     25     {
     26         G[i].clear();
     27         rG[i].clear();
     28         vc[i].clear();
     29         vis[i]=0;
     30         last[i]=-1;
     31         deg[i]=0;
     32         next[i]=-1;
     33     }
     34 }
     35 void dfs(int v)
     36 {
     37     vis[v]=1;
     38     for(int i=0;i<G[v].size();i++)
     39     {
     40         if(!vis[G[v][i]])dfs(G[v][i]);
     41     }
     42     vs.push_back(v);
     43 }
     44 void rdfs(int v,int k)
     45 {
     46     vis[v]=1;
     47     cmp[v]=k;
     48     vc[k].push_back(v);
     49     for(int i=0;i<rG[v].size();i++)
     50     {
     51         if(!vis[rG[v][i]])rdfs(rG[v][i],k);
     52     }
     53 }
     54 int scc()
     55 {
     56     memset(vis,0,sizeof(vis));
     57     vs.clear();
     58     for(int i=0;i<V;i++)
     59     {
     60         if(!vis[i])dfs(i);
     61     }
     62     memset(vis,0,sizeof(vis));
     63     int k=0;
     64     for(int i=vs.size()-1;i>=0;i--)
     65     {
     66         if(!vis[vs[i]])rdfs(vs[i],k++);
     67     }
     68     return k;
     69 }
     70 int main()
     71 {
     72     ios::sync_with_stdio(false);
     73     int t;
     74     cin>>t;
     75     while(t--)
     76     {
     77         int n,m;
     78         cin>>n>>m;
     79         V=n;
     80         init(n);
     81         int u,v;
     82         for(int i=0;i<m;i++)
     83         {
     84             cin>>u>>v;
     85             add_edge(--u,--v);
     86         }
     87         int k=scc();
     88         memset(vis,0,sizeof(vis));
     89         int flag=1;
     90         int num=0;
     91         for(int i=0;i<k;i++)
     92         {
     93             for(int j=0;j<vc[i].size();j++)
     94             {
     95                 u=vc[i][j];
     96                 for(int l=0;l<G[u].size();l++)
     97                 {
     98                     v=G[u][l];
     99                     if(cmp[u]!=cmp[v])
    100                     {
    101                         if(last[cmp[v]]==-1)
    102                         {
    103                             last[cmp[v]]=cmp[u];
    104                         }
    105                         else if(last[cmp[v]]==cmp[u])continue;
    106                         else flag=0;
    107                         if(next[cmp[u]]==-1)
    108                         {
    109                             next[cmp[u]]=cmp[v];
    110                         }
    111                         else if(next[cmp[u]]==cmp[v])
    112                         {
    113                             continue;
    114                         }
    115                         else flag=0;
    116                     }
    117                 }
    118             }
    119         }
    120         for(int i=0;i<k;i++)
    121         {
    122             if(last[i]==-1)num++;
    123         }
    124         if(flag&&num==1)cout<<"Yes"<<endl;
    125         else cout<<"No"<<endl;
    126     }
    127 
    128     return 0;
    129 }
    代码君
  • 相关阅读:
    opengl像素格式管理
    opengl的体系结构
    符号文件——Windows 应用程序调试必备
    [Study Note] Patterns in Practice 20100404
    “在我的机器上可以运行”症状自查(Windows编程)
    [Study Note] Patterns in Practice 20100402
    [Study Note] Patterns in Practice 20100406
    [Study Note] Design and Testability 20100410
    [Study Note] Patterns in Practice 20100403
    [Study Note] Design and Testability 20100411
  • 原文地址:https://www.cnblogs.com/fraud/p/4160339.html
Copyright © 2020-2023  润新知