POJ2762 Going from u to v or from v to u?

来源:互联网 发布:淘宝代购百丽是正品吗 编辑:程序博客网 时间:2024/05/18 01:01

Description

Going from u to v or from v to u?
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?
给定一个有向图,判断是否对于任何两个点u,v
总存在u-->v 或者v-->u.

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(0the 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
说白了就是问你这整张图连不连通,这个我们很容易想到强连通分量,既然这样我们就可以考虑缩点,能缩点的一定是满足条件的,那么缩完点之后判断是否是单链并且只有一个出度为0的点,好,既然是这样,如何去判断?除了首尾其余所有的点都只有一个父亲和一个儿子,那不就是单链。还有,如果缩点前是单链,直接输出就好了。

代码

#include<cstdio>#include<iostream>#include<cstring>using namespace std;int nex[10001],pre[10001],son[10001],n,m,T,dfn[10001],fa[10001],low[10001],tot,a[10001],b[10001],st[10001],used[10001],popp[10001];char ch; bool ok;void read(int &x){    for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;    for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());    if (ok) x=-x;}inline void add(int x,int y){    nex[++tot]=pre[x];    fa[y]++;    son[x]++;    pre[x]=tot;}int top,sum,total,ll,tottt;inline void dfs(int now){    st[++top]=now;    sum++;    dfn[now]=low[now]=sum;    int ttt=top;    for(int i=pre[now];i;i=nex[i])        if(!used[b[i]])        {            if(!dfn[b[i]])                dfs(b[i]);            low[now]=min(low[now],low[b[i]]);        }    if(low[now]==dfn[now])    {        total++;        for(int i=ttt;i<=top;i++)            used[st[i]]=total;        top=ttt-1;    }}int tepan(){    if(total==1)return 1;     int f=0,p=0,l=0;    for(int i=1;i<=total;i++)        if(fa[i]==1&&son[i]==1)f++;        else        {            if(fa[i]!=1)                 p=fa[i];            if(son[i]!=1)                l=son[i];        }    if(f==total-2&&p==0&&l==0)return 1;    return 0;}int main(){    read(T);    while(T--)    {        tot=0;total=0;top=0;int ans=0,ans1=0;        memset(st,0,sizeof(st));        memset(dfn,0,sizeof(dfn));        memset(low,0,sizeof(low));        memset(used,0,sizeof(used));        memset(pre,0,sizeof(pre));        memset(son,0,sizeof(son));        memset(fa,0,sizeof(fa));        memset(popp,0,sizeof(popp));        read(n),read(m);        for(int i=1;i<=m;i++)            read(a[i]),read(b[i]),add(a[i],b[i]);        total=n;        if(tepan())        {puts("Yes");continue;}        total=0;        tot=0;        for(int i=1;i<=n;i++)            if(!used[i])dfs(i);        memset(son,0,sizeof(son));        memset(fa,0,sizeof(fa));        for(int i=1;i<=m;i++)            if(used[a[i]]!=used[b[i]])add(used[a[i]],used[b[i]]),popp[used[a[i]]]++;        for(int i=1;i<=total;i++)            if(!popp[i])ans++;        if(tepan()&&ans==1)puts("Yes");        else            puts("No");    }}


阅读全文
0 0
原创粉丝点击