Test instructions: Given a directional graph has M-bar one-way edge, to determine whether any two points can reach (a can to B or B can reach a or each other), that is to ask
Weak Unicom component.
Algorithm:
First, the strong connected components are obtained by shrinking points. Then re-build the map to determine whether the new diagram is a single chain, that is, can not fork, if the fork will exist in the case of unreachable.
How to tell if it is a single chain?
There is only one point in each of the 0 points, that is, there is only one point in each queue.
(O (╯-╰) o ..... It seems to be the second time to record the original point pair with a pair, and then save the vector of the pair forgot to empty led WA to WA! )
#include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <vector > #define MAXN 1010#define maxm 20010using namespace std;struct node{int to,next;} Edge[maxm],edge2[maxm];int Head[maxn],cnt,n;int Clk,top,s[maxn],scc,dfn[maxn],low[maxn],belong[maxn];bool Instack [Maxn],vis[maxn];int head2[maxn],cnt2,in[maxn];typedef pair<int,int> pii;vector<pii> xx;queue<int > q;void Add (int x,int y) {edge[cnt].to = y; Edge[cnt].next = Head[x]; HEAD[X] = cnt++;} void add2 (int x,int y) {edge2[cnt2].to = y; Edge2[cnt2].next = Head2[x]; HEAD2[X] = cnt2++;} void Dfs (int x) {dfn[x] = low[x] = clk++; s[top++] = x; Instack[x] = true; for (int i=head[x];i!=-1;i = edge[i].next) {int u = edge[i].to; if (dfn[u]==-1) {dfs (U); Low[x] = min (low[u],low[x]); } else if (Instack[u]) {low[x] = min (Low[x],dfn[u]); }} if (Low[x]==dfn[x]) { int u; scc++; do {u = s[--top]; Instack[u]=false; Belong[u] = SCC; }while (u!=x); }}void Tarjan () {memset (dfn,-1,sizeof (DFN)); memset (instack,0,sizeof (instack)); Memset (Belong,0,sizeof (belong)); CLK = top = SCC = 0; for (int i=1;i<=n;i++) {if (dfn[i]==-1) DFS (i); }}bool topo () {memset (vis,0,sizeof (VIS)); int c = 0; while (!q.empty ()) Q.pop (); for (int i=1;i<=scc;i++) {if (!in[i]) {C + +; Q.push (i); }} if (c>1) return false; while (!q.empty ()) {int u = q.front (); Q.pop (); if (Vis[u]) continue; Vis[u] = true; c = 0; for (int i=head2[u];i!=-1;i=edge2[i].next) {int v = edge2[i].to; in[v]--; if (!in[v]) {Q.push (v); C + +; }} if (c>1) return false; } return true; int main () {int m,a,b,t; scanf ("%d", &t); while (t--) {scanf ("%d%d", &n,&m); memset (head,-1,sizeof (head)); memset (In,0,sizeof (in)); Xx.clear (); CNT = 0; for (int i=1;i<=m;i++) {scanf ("%d%d", &a,&b); Add (A, b); Xx.push_back (Make_pair (A, b)); } Tarjan (); memset (head2,-1,sizeof (head2)); Cnt2 = 0; for (int i=0;i<xx.size (); i++) {int u = xx[i].first,v = Xx[i].second; if (Belong[u]!=belong[v]) {ADD2 (belong[u],belong[v]); in[belong[v]]++; }} if (Topo ()) printf ("yes\n"); else printf ("no\n"); } return 0;}