poj 2762 Going from u to v or from v to u?(强连通分量)

来源:互联网 发布:单片机的发展趋势 编辑:程序博客网 时间:2024/04/30 14:15

题目链接

Going from u to v or from v to u?
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 14729 Accepted: 3894

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

题意:给一个有向图判断,对于图中任意两个点(u,v),一定存在路径u->v,或v->u。

题解:将强连通分量缩点以后,图一定是DAG,要让该图满足条件,那么一定存在该图的子图为一条包含所有点的链。所以若该图拓扑排序的结果唯一,那么该图一定满足条件。代码如下:

#include<stdio.h>#include<iostream>#include<queue>#include<algorithm>#include<stack>#include<math.h>#include<vector>#include<string.h>#define nn 11000#define inff 0x3fffffffusing namespace std;int n,m;struct node{    int en,next;}E[nn*nn];int p[nn],num;void init(){    memset(p,-1,sizeof(p));    num=0;}void add(int st,int en){    E[num].en=en;    E[num].next=p[st];    p[st]=num++;}int dfn[nn],low[nn],df;int cnt;int fa[nn];bool insta[nn];stack<int>sta;void dfs(int id){    dfn[id]=low[id]=++df;    sta.push(id);    insta[id]=true;    int i,w;    for(i=p[id];i+1;i=E[i].next)    {        w=E[i].en;        if(dfn[w]==-1)        {            dfs(w);            low[id]=min(low[id],low[w]);        }        else if(insta[w])            low[id]=min(low[id],dfn[w]);    }    if(low[id]==dfn[id])    {        ++cnt;        int ix;        while(1)        {            ix=sta.top();            sta.pop();            insta[ix]=false;            fa[ix]=cnt;            if(ix==id)                break;        }    }}int rd[nn];vector<int>ans;vector<int>tu[nn];void solve(){    memset(rd,0,sizeof(rd));    memset(insta,false,sizeof(insta));    memset(dfn,-1,sizeof(dfn));    df=cnt=0;    int i,j,w;    for(i=1;i<=n;i++)    {        if(dfn[i]==-1)        {            dfs(i);        }    }    for(i=0;i<=1100;i++)        tu[i].clear();    for(i=1;i<=n;i++)    {        for(j=p[i];j+1;j=E[j].next)        {            w=E[j].en;            if(fa[w]!=fa[i])            {                tu[fa[i]].push_back(fa[w]);                rd[fa[w]]++;            }        }    }}void tuopu(){    int i;    for(i=1;i<=cnt;i++)    {        if(rd[i]==0)            sta.push(i);    }    while(sta.size())    {        if(sta.size()>1)            break;        int ix=sta.top();        sta.pop();        for(i=0;i<tu[ix].size();i++)        {            rd[tu[ix][i]]--;            if(rd[tu[ix][i]]==0)            {                sta.push(tu[ix][i]);            }        }    }    if(sta.size())    {        puts("No");        while(sta.size())            sta.pop();    }    else        puts("Yes");}int main(){    int i,t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        int u,v;        init();        for(i=1;i<=m;i++)        {            scanf("%d%d",&u,&v);            add(u,v);        }        solve();        tuopu();    }    return 0;}


0 0
原创粉丝点击