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

来源:互联网 发布:酷派5263更改网络 编辑:程序博客网 时间:2024/06/07 05:04
Time Limit: 2000MS Memory Limit: 65536KTotal 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

13 31 22 33 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\n");91         else printf("No\n");92     }93     return 0;94 }

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

0 0
原创粉丝点击