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

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
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七情六欲·

学生党不容易~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值