Tarjan + Topsort
Tarjan 缩点
Topsort 判断
Topsort 判断:
在DAG中
若初始状态下存在多于1个入度为0的点
则说明这些 入度为0的点之间不会有路径可达
若不存在入度为0的点,则状态为Yes
若只存在1个入度为0的点,将该点指出的边删除
继续上述判断
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> const int N = 1010, M = N * 6; #define gc getchar() inline int read() { int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } int head[N], head_2[N], cnt; struct Node {int u, v, nxt;}; Node G[M], E[M]; int In[N], n, m; int Low[N], Dfn[N], Stack[N], Belong[N], Scc, Tim, topp; bool vis[N]; inline void Add_1(int u, int v) {G[++ cnt].v = v; G[cnt].nxt = head[u]; head[u] = cnt;} inline void Add_2(int u, int v) {E[++ cnt].v = v; E[cnt].nxt = head_2[u]; head_2[u] = cnt; In[v] ++;} inline void Clear() { memset(head, -1, sizeof head); memset(head_2, -1, sizeof head_2); memset(In, 0, sizeof In); memset(Low, 0, sizeof Low); memset(Dfn, 0, sizeof Dfn); memset(vis, 0, sizeof vis); topp = cnt = Scc = Tim = 0; } inline void Init() { n = read(), m = read(); for(int i = 1; i <= m; i ++) Add_1(read(), read()); } void Tarjan(int x) { Low[x] = Dfn[x] = ++ Tim; Stack[++ topp] = x; vis[x] = 1; for(int i = head[x]; ~ i; i = G[i].nxt) { int v = G[i].v; if(!Dfn[v]) { Tarjan(v); Low[x] = std:: min(Low[x], Low[v]); } else if(vis[v]) Low[x] = std:: min(Low[x], Low[v]); } if(Dfn[x] == Low[x]) { vis[x] = 0, Belong[x] = ++ Scc; while(Stack[topp] != x) { vis[Stack[topp]] = 0, Belong[Stack[topp]] = Scc; topp --; } topp --; } } inline void Rebuild() { cnt = 0; for(int u = 1; u <= n; u ++) for(int i = head[u]; ~ i; i = G[i].nxt) if(Belong[u] != Belong[G[i].v]) Add_2(Belong[u], Belong[G[i].v]); } void Topsort() { if(Scc == 1) {puts("Yes"); return ;} int Ans(0), flag; for(int i = 1; i <= Scc; i ++) if(!In[i]) Ans ++, flag = i; if(Ans > 1) {puts("No"); return ;} int temp = Scc; for(; temp; temp --) { Ans = 0; for(int i = head_2[flag]; ~ i; i = E[i].nxt) { int v = E[i].v; In[v] --; if(!In[v]) Ans ++, flag = v; } if(Ans > 1) {puts("No"); return ;} if(!Ans) {puts("Yes"); return ;} } puts("Yes"); return ; } void Work() { Clear(); Init(); for(int i = 1; i <= n; i ++) if(!Dfn[i]) Tarjan(i); Rebuild(); Topsort(); } int main() { int t = read(); for(; t; t --, Work()); return 0; }