Going from u to V or from V to u?
Time limit:2000 ms |
|
Memory limit:65536 K |
Total submissions:14474 |
|
Accepted:3804 |
Description
In order to make their sons brave, Jiajia and wind take them to a big cave. the cave has n rooms, and one-way corridors connecting some rooms. each time, wind choose two rooms X and Y, and ask one of their little sons go from one to the other. the son can either go from X to Y, or from Y to X. wind promised that her tasks are all possible, but she actually doesn' t know how to decide if a task is Po Ssible. to make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. given a cave, can you tell Jiajia whether wind can randomly choose two rooms without worrying about anything?
Input
The first line contains a single integer t, the number of test cases. And followed t cases.
The first line for each case contains two integers n, m (0 <n <1001, m <6000), the number of rooms and corridors in the cave. the next M lines each contains two integers U and V, indicating that there is a corridor connecting room U and Room V directly.
Output
The output shoshould contain t lines. Write 'yes' if the cave has the property stated above, or 'no' otherwise.
Sample Input
13 31 22 33 1
Sample output
Yes
Question: n vertices and m edges. Determine whether V or V can reach U at any two vertices.
Train of Thought: After the Tarjan point is reduced, you can determine whether a directed acyclic graph is a straight line. The condition is: the starting point, the ending point has only one, and the starting degree is 1 or 0.
# Include <iostream> # include <cstdio> # include <cstring> # include <vector> # include <string> # include <algorithm> # include <queue> # include <stack> using namespace STD; const int maxn = 1000 + 10; const int MaxE = 6000 + 10; struct edge {int V, NXT;} e [MaxE]; int head [maxn]; int N, m; stack <int> S; queue <int> que; int in [maxn], out [maxn]; int dfn [maxn], lown [maxn], sccno [maxn]; int dfs_clk, scc_cnt, nume; void Init () {dfs_clk = 0; scc_cnt = 0; nume = 1; while (! S. Empty () S. Pop (); While (! Que. empty () que. pop (); memset (sccno, 0, sizeof sccno); memset (dfn, 0, sizeof dfn); memset (in, 0, sizeof in); memset (Out, 0, sizeof out); memset (Head, 0, sizeof head);} void addedge (int u, int v) {e [++ nume]. NXT = head [u]; E [nume]. V = V; head [u] = nume;} void Tarjan (int u) {dfn [u] = lown [u] = ++ dfs_clk; S. push (U); For (INT I = head [u]; I; I = E [I]. NXT) {int v = E [I]. v; If (! Dfn [v]) {Tarjan (V); lown [u] = min (lown [u], lown [v]);} else if (! Sccno [v]) {// The ancestor lown [u] = min (lown [u], dfn [v]) that can be reached in the stack;} if (lown [u] = dfn [u]) {scc_cnt ++; while (true) {int x = S. top (); S. pop (); sccno [x] = scc_cnt; If (x = u) Break ;}} int main () {int ncase; CIN >> ncase; while (ncase --) {Init (); scanf ("% d", & N, & M); int A, B; For (INT I = 0; I <m; I ++) {scanf ("% d", & A, & B); addedge (a, B) ;}for (INT I = 1; I <= N; I ++) {If (! Dfn [I]) Tarjan (I) ;}for (INT I = 1; I <= N; I ++) {int K = sccno [I]; for (Int J = head [I]; j = E [J]. NXT) {int d = sccno [E [J]. v]; If (K! = D) {in [d] ++; out [k] ++ ;}} int TR = 0, TS = 0; bool flag = true; for (INT I = 1; I <= scc_cnt; I ++) {If (in [I] = 0) {tr ++; if (out [I]> 1) {flag = false; break ;}} if (out [I] = 0) {ts ++ ;}} if (flag & TR = 1 & TS = 1) {printf ("Yes \ n");} else {printf ("NO \ n ");}} return 0 ;}