• POJ 2762 Going from u to v or from v to u? Tarjan算法 学习例题


    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 17104   Accepted: 4594

    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

    Source

    POJ Monthly--2006.02.26,zgl & twb
    题目大意:n个山洞,对于每两个山洞s,e,都满足s可以到达e或者e可以到达s,则输出Yes,否则输出No。(s到e或者e到s满足一个就可以)
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<stack>
     5 #define maxm 6010
     6 #define maxn 1010
     7 using namespace std;
     8 int T,n,m;
     9 struct edge{
    10     int u,v,next;
    11 }e[maxm],ee[maxm];
    12 int head[maxn],js,headd[maxn],jss;
    13 bool exist[maxn];
    14 int visx,cur;// cur--缩出的点的数量 
    15 int dfn[maxn],low[maxn],belong[maxn];
    16 int rudu[maxn],chudu[maxn];
    17 stack<int>st;
    18 void init(){
    19     memset(rudu,0,sizeof(rudu));memset(chudu,0,sizeof(chudu));
    20     memset(head,0,sizeof(head));memset(headd,0,sizeof(headd));
    21     jss=js=visx=cur=0;
    22     memset(exist,false,sizeof(exist));
    23     while(!st.empty())st.pop();
    24     memset(dfn,-1,sizeof(dfn));memset(low,-1,sizeof(low));
    25     memset(belong,0,sizeof(belong));
    26 }
    27 void add_edge1(int u,int v){
    28     e[++js].u=u;e[js].v=v;
    29     e[js].next=head[u];head[u]=js;
    30 }
    31 void tarjan(int u){
    32     dfn[u]=low[u]=++visx;
    33     exist[u]=true;
    34     st.push(u);
    35     for(int i=head[u];i;i=e[i].next){
    36         int v=e[i].v;
    37         if(dfn[v]==-1){
    38             tarjan(v);
    39             if(low[v]<low[u]) low[u]=low[v];
    40         }
    41         else if(exist[v]&&low[u]>dfn[v]) low[u]=dfn[v];
    42     }
    43     int j; 
    44     if(low[u]==dfn[u]){
    45         ++cur;
    46         do{
    47             j=st.top();st.pop();exist[j]=false;
    48             belong[j]=cur;
    49         }while(j!=u);
    50     }
    51 }
    52 void add_edge2(int u,int v){
    53     ee[++jss].u=u;ee[jss].v=v;
    54     ee[jss].next=headd[u];headd[u]=jss;
    55 }
    56 bool topo()
    57 {
    58     int tp=0,maxt=0;
    59     for(int i=1;i<=cur;i++)
    60     {
    61         if(rudu[i]==0){
    62             tp++;  
    63         }
    64         if(chudu[i]>maxt)maxt=chudu[i];
    65     }
    66     if(tp>1)return 0;// 入读等于0的缩点只能有一个 否则.. 
    67     if(maxt>1)return 0;
    68     return 1;
    69 }
    70 int main()
    71 {
    72     scanf("%d",&T);
    73     while(T--){
    74         scanf("%d%d",&n,&m);
    75         init();
    76         int u,v;
    77         for(int i=0;i<m;i++){
    78             scanf("%d%d",&u,&v);add_edge1(u,v);
    79         }
    80         for(int i=1;i<=n;i++){// 求强连通分量
    81             if(dfn[i]==-1) tarjan(i);
    82         }
    83         for(int i=1;i<=js;i++){
    84             int u=e[i].u,v=e[i].v;
    85             if(belong[u]!=belong[v]){
    86                 add_edge2(belong[u],belong[v]);
    87                 rudu[belong[v]]++;chudu[belong[u]]++;
    88             }
    89         }
    90         if(topo()==1) printf("Yes
    ");
    91         else printf("No
    ");
    92     }
    93     return 0;
    94 }

    思路:首先建一个有向图,进行Tarjan算法,进行缩点,缩完点之后,再建一张有向图(这张图只能成一条链),对其进行检验,入度为0的店只能有一个或没有。。

  • 相关阅读:
    SpringBoot 日志
    springboot 自动配置
    性能测试步骤
    性能测试与压力测试
    Shell学习八:调用其它shell文件
    Shell学习七:重定向
    Linux mysql服务重启
    Shell学习六:流程控制
    Shell学习五:test参数的使用
    Shell学习四:echo和print输出
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6238775.html
Copyright © 2020-2023  润新知