Going from u to v or from v to u?
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 14052 | Accepted: 3676 |
Description
Input
Output
Sample Input
1
3 3
1 2
2 3
3 1
Sample Output
Yes
Source
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define clear( a , x ) memset ( a , x , sizeof a ) const int MAXN = 1005 ; const int MAXE = 10000 ; const int MAXQ = 10000 ; const int INF = 0x3f3f3f3f ; struct Edge { int v , n ; Edge ( int var = 0 , int next = 0 ) : v(var) , n(next) {} } ; struct SCC { Edge edge[MAXE] ; int adj[MAXN] , cntE ; int Dfn[MAXN] , Low[MAXN] , dfs_clock ; int scc[MAXN] , scc_cnt ; int S[MAXN] , top ; bool ins[MAXN] ; void init () { top = 0 ; cntE = 0 ; scc_cnt = 0 ; dfs_clock = 0 ; clear ( ins , 0 ) ; clear ( Dfn , 0 ) ; clear ( adj , -1 ) ; } void addedge ( int u , int v ) { edge[cntE] = Edge ( v , adj[u] ) ; adj[u] = cntE ++ ; } void Tarjan ( int u ) { Dfn[u] = Low[u] = ++ dfs_clock ; S[top ++] = u ; ins[u] = 1 ; for ( int i = adj[u] ; ~i ; i = edge[i].n ) { int v = edge[i].v ; if ( !Dfn[v] ) { Tarjan ( v ) ; Low[u] = min ( Low[u] , Low[v] ) ; } else if ( ins[v] ) Low[u] = min ( Low[u] , Dfn[v] ) ; } if ( Low[u] == Dfn[u] ) { ++ scc_cnt ; while ( 1 ) { int v = S[-- top] ; ins[v] = 0 ; scc[v] = scc_cnt ; if ( v == u ) break ; } } } void find_scc ( int n ) { REPF ( i , 1 , n ) if ( !Dfn[i] ) Tarjan ( i ) ; } } ; struct DAG { Edge edge[MAXE] ; int adj[MAXN] , cntE ; int in[MAXN] ; int d[MAXN] ; int num[MAXN] ; int Q[MAXQ] ; int head , tail ; void init () { cntE = 0 ; clear ( in , 0 ) ; clear ( num , 0 ) ; clear ( adj , -1 ) ; } void addedge ( int u , int v ) { edge[cntE] = Edge ( v , adj[u] ) ; adj[u] = cntE ++ ; } int topo ( int n , int tot ) { head = tail = 0 ; clear ( d , 0 ) ; REPF ( i , 1 , n ) if ( !in[i] ) d[Q[tail ++] = i] = num[i] ; while ( head != tail ) { int u = Q[head ++] ; for ( int i = adj[u] ; ~i ; i = edge[i].n ) { int v = edge[i].v ; if ( d[v] < d[u] + num[v] ) d[v] = d[u] + num[v] ; if ( 0 == ( -- in[v] ) ) Q[tail ++] = v ; } } REPF ( i , 1 , n ) { if ( d[i] == tot ) return 1 ; } return 0 ; } } ; SCC C ; DAG D ; int read ( int &x ) { x = 0 ; char c = ' ' ; while ( c < '0' || c > '9' ) c = getchar () ; if ( c == -1 ) return 0 ; while ( c >= '0' && c <= '9' ) { x = x * 10 + c - '0' ; c = getchar () ; } return 1 ; } void work () { int n , m ; int u , v ; C.init () ; read ( n ) , read ( m ) ; //scanf ( "%d%d" , &n , &m ) ; while ( m -- ) { read ( u ) , read ( v ) ; //scanf ( "%d%d" , &u , &v ) ; C.addedge ( u , v ) ; } C.find_scc ( n ) ; if ( C.scc_cnt == 1 ) { printf ( "Yes\n" ) ; return ; } D.init () ; REPF ( u , 1 , n ) for ( int i = C.adj[u] ; ~i ; i = C.edge[i].n ) { int v = C.edge[i].v ; if ( C.scc[u] != C.scc[v] ) { D.addedge ( C.scc[u] , C.scc[v] ) ; ++ D.in[C.scc[v]] ; } } REPF ( i , 1 , n ) ++ D.num[C.scc[i]] ; if ( D.topo ( C.scc_cnt , n ) ) printf ( "Yes\n" ) ; else printf ( "No\n" ) ; } int main () { int T ; scanf ( "%d" , &T ) ; while ( T -- ) work () ; return 0 ; }