POJ 2762 Going from u to v or from v to u?

来源:互联网 发布:pycuda 知乎 编辑:程序博客网 时间:2024/06/16 10:00

Going from u to v or from v to u?

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 17761 Accepted: 4766
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

#include<iostream>#include<cstring>#include<stack>#include<cstdio>using namespace std;const int maxn = 1010 ;const int maxm = 6010 ;stack<int> st;int chudu[maxn],rudu[maxn];int head[maxn],link[maxn],tot1,tot2;int belong[maxn],cur,dfn[maxn],low[maxn],visx;bool exist[maxn];struct Edge{ int from,to,next; }e[maxm],ee[maxm];void PrePare(){    memset(link,0,sizeof link );    memset(head,0,sizeof head );    memset(rudu,0,sizeof rudu );    memset(chudu,0,sizeof chudu );    tot1=tot2=visx=cur=0;    memset(exist,0,sizeof exist );    memset(dfn,-1,sizeof dfn );memset(low,-1,sizeof low );    memset(belong,0,sizeof belong );}void Add_Edge(int u,int v){ e[++tot1].to=v;e[tot1].from=u;e[tot1].next=head[u];head[u]=tot1; }void Add_Edgee(int u,int v){ ee[++tot2].to=v;e[tot2].next=link[u];link[u]=tot2; }int n,m;void Tarjan(int u){    dfn[u]=low[u]= ++visx;    exist[u]=true;st.push(u);    for(int i=head[u];i;i=e[i].next){        int v=e[i].to;        if(dfn[v]==-1){            Tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(exist[v]&&low[u]>dfn[v]) low[u]=dfn[v];    }    int k;    if(low[u]==dfn[u]){        ++cur;        do{            k=st.top();st.pop();exist[k]=false;            belong[k]=cur;        }while(k!=u);    }}bool Topo(){    int tp=0,maxt=0;    for(int i=1;i<=cur;i++){        if(rudu[i]==0){ tp++; }        if(chudu[i]>maxt)maxt=chudu[i];    }    if(tp>1)return 0;// 入度等于0的缩点只能有一个 否则..     if(maxt>1)return 0;    return 1;}int main(){    int T;cin>>T;    while(T--){        PrePare();        scanf("%d%d",&n,&m);        for(int i=1,u,v;i<=m;i++){            scanf("%d%d",&u,&v);            Add_Edge(u,v);        }        for(int i=1;i<=n;i++)            if(dfn[i]==-1) Tarjan(i);        for(int i=1;i<=tot1;i++){            int u=e[i].from,v=e[i].to;            if(belong[u]!=belong[v]){                Add_Edgee(belong[u],belong[v]);                rudu[belong[v]]++;chudu[belong[u]]++;            }        }        if(Topo()==1) printf("Yes\n");        else printf("No\n");    }    return 0;}
阅读全文
0 0