poj 2672

来源:互联网 发布:linux删除文件夹 编辑:程序博客网 时间:2024/05/23 01:57

题意:有 n 个房间,不同房间之间有单向通道,问是否任意两个房间 A 、B 都可以从 A 到 B 或从 B 到 A(有一条有就可以)。

那就是问缩点之后的图能不能是一条线下来。因为连通分量里的点肯定能互相到达,而不是连通分量的点如果是一条线也可以啊。

所以是强连通家拓扑排序就可以ok了。

#include<stdio.h>#include<string.h>#include<stack>#include<queue>#include<algorithm>using namespace std;#define ll long long#define me(a,b) memset(a,b,sizeof(a))struct node{    int u,v,next;}e[12000];struct node1{    int u,v,next;}e2[12000];int head[3000],in[3000],top,top2,cnt,tot,dfn[3000],low[3000],scnt[3000],head2[3000];void add(int u,int v){    e[top].u=v;    e[top].v=u;    e[top].next=head[u];    head[u]=top++;}void add2(int u,int v){    e2[top2].u=v;    e2[top2].v=u;    e2[top2].next=head2[u];    head2[u]=top2++;}stack<int>q;void tarjan(int x){    dfn[x]=low[x]=++tot;    q.push(x);    for(int i=head[x];i!=-1;i=e[i].next)    {        int u=e[i].u;        if(!dfn[u])        {            tarjan(u);            low[x]=min(low[u],low[x]);        }        else if(!scnt[u])        {            low[x]=min(dfn[u],low[x]);        }    }    if(low[x]==dfn[x])    {        int v=-1;        cnt++;        while(v!=x)        {            v=q.top();            q.pop();            scnt[v]=cnt;        }    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n,m;        scanf("%d%d",&n,&m);        me(head,-1);        me(dfn,0);        me(head2,-1);        me(low,0);        me(in,0);        me(scnt,0);        top=tot=cnt=top2=0;        for(int i=0;i<m;i++)        {            int a,b;            scanf("%d%d",&a,&b);            add(a,b);        }        for(int i=1;i<=n;i++)        {            if(!dfn[i])            tarjan(i);        }        //printf("%d....\n",cnt);        for(int i=0;i<top;i++)        {            int u=e[i].u;            int v=e[i].v;            if(scnt[u]!=scnt[v])            {                add2(scnt[v],scnt[u]);                in[scnt[u]]++;            }        }        queue<int>p;        for(int i=1;i<=cnt;i++)        {            if(!in[i])            {                p.push(i);            }        }        int flag=1;        while(!p.empty())        {            if(p.size()>=2)            {                flag=0;                break;            }            int f=p.front();            p.pop();            for(int i=head2[f];i!=-1;i=e2[i].next)            {                int u=e2[i].u;//printf("%d..\n",u);                in[u]--;                if(!in[u])                {                    p.push(u);                }            }        }        if(flag)        {            printf("Yes\n");        }        else printf("No\n");    }}

原创粉丝点击