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;}