题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269
题意:略
题解:trajan模版直接求强连通分量。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 1e4 + 10; const int M = 1e5 + 10; struct Edge { int v , next; }edge[M]; int head[N] , e; int Low[N] , DFN[N] , Stack[N] , Belong[N]; int Index , top; int scc; bool Instack[N]; int num[N]; void init() { e = 0; memset(head , -1 , sizeof(head)); } void add(int u , int v) { edge[e].v = v , edge[e].next = head[u] , head[u] = e++; } void Tarjan(int u) { int v; Low[u] = DFN[u] = ++Index; Stack[top++] = u; Instack[u] = true; for(int i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v; if(!DFN[v]) { Tarjan(v); Low[u] = min(Low[u] , Low[v]); } else if(Instack[v]) Low[u] = min(Low[u] , DFN[v]); } if(Low[u] == DFN[u]) { scc++; do { v = Stack[--top]; Instack[v] = false; Belong[v] = scc; num[scc]++; } while(v != u); } } int main() { int a , b , n , m; while(scanf("%d%d" , &n , &m) != EOF) { if(n == 0 && m == 0) break; init(); for(int i = 0 ; i < m ; i++) { scanf("%d%d" , &a , &b); add(a , b); } memset(DFN , 0 , sizeof(DFN)); memset(Instack , false , sizeof(Instack)); memset(num , 0 , sizeof(num)); Index = scc = top = 0; for(int i = 1 ; i <= n ; i++) if(!DFN[i]) Tarjan(i); if(scc == 1) printf("Yes "); else printf("No "); } return 0; }