Determines whether a directed graph is connected by a point between rings.
Cactus means Cactus, not image.
General idea:
Search from the start point 0, and search for the ring will drop the ring mark (the point that the ring is connected to the search path does not mark, and the search will continue from this point ). After the search, all the searched points are used as the start point for such search. If the previous mark point is found (the start point is not counted), the edge exists in two rings. Complexity O (e) =. =
Pseudocode:
Bool function (){
1. Put the starting point 0 into a queue (Stack is also acceptable, it doesn't matter, it only plays a storage role, but to distinguish it from the following stack, put it into queue. In fact, the Code is also a stack: pstk );
2. When the queue is not empty, take out the front element and mark it as start. From this point on, perform a deep search. The queue is empty and jumps to 7th sentences;
3. When searching, you need to record the edge of the current search for each vertex. The next search starts from this point, and the execution may find that the current vertex has no edge to be searched, check whether the vertex is a start vertex. If not, 0 is returned (indicating that it is not a strongly connected graph, which is easy to prove). If yes, roll it back to the stack, mark it (in fact, if this is not 0, it must have been marked) and execute 2nd sentences;
4. Put the current vertex in the stack, instk [u] = 1. If the vertex is marked and not start, 0 is returned (indicating that the edge exists in two rings, verifiable );
5. If you find a vertex that is not in the stack, put it into the stack. At the same time, instk [u] = 1, and then put the U into the queue. From this point, you can search, jump back to 3rd sentences;
6. Otherwise, this point is in the stack, stack all points between the stack and the element (except the point just found), and mark it, start searching from this point and continue to execute from the first sentence;
7. Scan all vertices. If a mark is not detected, then even weak connections are not. 0 is returned (this sentence is skipped in the code, indicates that all data is given at least weakly connected, so you are too lazy to add it). Otherwise, 1 is returned.
}
# Include <iostream> # include <queue> using namespace STD; struct edge {int U, V, next ;}; edge [50000]; int N, head [20000], en; void insert (int u, int v) {edge [En]. U = u; edge [En]. V = V; edge [En]. next = head [u]; head [u] = EN ++;} void get_data () {memset (Head,-1, sizeof (head); en = 0; int A, B; scanf ("% d", & N); While (scanf ("% d", & A, & B), a | B) {insert (a, B) ;}} int cur [20000], pstk [20000], PSN, STK [20000], Sn; bool mark [20000], instk [20000]; bool run () {int I; for (I = 0; I <n; I ++) cur [I] = head [I]; // initialize the current edge memset (mark, 0, sizeof (Mark); memset (instk, 0, sizeof (instk); Sn = PSN = 0; pstk [PSN ++] = 0; int U, V, start; while (PSN) {start = u = pstk [-- PSN]; // 2nd sentence if (cur [u] =-1) continue; while (true) {// ---- 3rd sentence ---- if (cur [u] =-1) {If (u = Start) {sn --; Mark [u] = 1; break;} else return 0;} // -------------- STK [Sn ++] = u; instk [u] = 1; for (; cur [u]! =-1;) {v = edge [cur [u]. v; cur [u] = edge [cur [u]. next; // set the current edge to the next one to prepare for the next search. If (V! = Start & Mark [v]) return 0; // 4th if (! Instk [v]) {// 5th sentence pstk [PSN ++] = V; u = V; break;} else {// 6th sentence while (STK [sn-1]! = V) {mark [STK [sn-1] = 1; sn --;} u = V ;}}}// 7th sentence =. = Return 1 ;}int main () {int t; scanf ("% d", & T); While (t --) {get_data (); If (run ()) printf ("Yes \ n"); else printf ("NO \ n");} return 0 ;}