poj 2762

来源:互联网 发布:淘宝美工是做什么工作 编辑:程序博客网 时间:2024/05/23 02:02
#include <iostream>#include <cstdio>#include <cstring>#define N 1010#define M 6060using namespace std;struct Node{    int v,next;}edge[M], edge2[M];int head[N], head2[N], SCC, num, top;int low[N], dfn[N], sta[N], sn[N], id[N];bool mark[N];void add_edge(Node edge[], int head[], int u, int v,int &num ){    edge[num].v = v;    edge[num].next = head[u];    head[u] = num++;}void get_map( int n, int m ){    int num = 0, u, v;    for( int i = 0; i <= n; i ++ )        head[i] = -1;    while( m -- )    {        scanf("%d%d",&u,&v);        add_edge( edge,head,u,v,num);    }}void dfs( int u ){    low[u] = dfn[u] = ++ num;    mark[u] = true;    sta[top++] = u;    for( int p = head[u]; p!=-1; p = edge[p].next )    {        int v = edge[p].v;        if( !dfn[ v ])        {            dfs(v);            low[u] = min(low[u],low[v]);        }        else if( mark[v] && dfn[v] < low[u] ) low[u] = dfn[v];    }    if( low[u] == dfn[u] )    {        SCC++;        do        {            u = sta[--top];            mark[u] = false;            sn[u] = SCC;        }        while( low[u] != dfn[u] );    }}bool bfs( int s ){    int front = 0, rear = 0, sum = 0;    low[rear++] = s;    while( front!=rear )    {        int u = low[front++];        sum++;        s = -1;        for( int p = head2[u]; p!=-1; p = edge2[p].next ) if( --id[edge2[p].v] == 0 )        {            if( s != -1 ) return false;            else s = edge2[p].v;        }        if( s != -1 ) low[rear++] = s;    }    if( sum!=SCC ) return false;    else return true;}bool tarjan( int n ){    SCC = num = 0;    for( int i = 0; i <= n; i ++ )    {        mark[i] = false;        dfn[i] = low[i] = id[i] = sn[i] = 0;        head2[i] = -1;    }    for( int i = 1; i <= n; i ++ )        if( !dfn[i] ) dfs(i);    if( SCC<=1 ) return true;    num = 0;    for( int u = 1; u <= n; u ++ )    for( int p = head[u]; p!=-1; p = edge[p].next )    {        int v = edge[p].v;        if( sn[u] != sn[v] )        {            id[ sn[v] ]++;            add_edge(edge2,head2,sn[u],sn[v], num );        }    }    int s = -1;    for( int i = 1; i <= SCC; i ++ )        if( id[i] == 0 )            if( s == -1 ) s = i;            else return false;    if( bfs(s) )  return true;    else return false;}int main(){    int cas, m, n;    scanf("%d",&cas);    while( cas -- )    {        scanf("%d%d",&n,&m);        get_map(n,m);        if( tarjan(n) ) printf("Yes\n");        else printf("No\n");    }    return 0;}