We have discussed the method of finding Euler's circuit and Euler's path in an undirected graph. It can be determined directly based on the degree. The premise is that it is a connected graph.
This question involves both directed and directed edges, and then asks the Euler loop.
The maximum stream is used.
Specific processing method.
First, we can set an edge randomly for an undirected edge. After the edge is set, obtain the outbound degree of each vertex. If the difference between the inbound and outbound degrees of a certain point is an odd number, the Euler Loop cannot be formed.
The degree difference between all vertices is an even number. For directed edges, we do not need to deal with them.
For undirected edges, we set the direction of the initial Random Edge. The traffic is + 1, that is, if a undirected edge, a-B, we initially set the edge to a-> B, then we will increase the traffic of a-> B by 1.
Then, if the exit degree is greater than the inbound degree for each vertex with an even number of outbound degrees. Then we connect a second to the edge of the point, and the traffic is (outbound-Inbound)/2.
Similarly, for an edge with an inbound degree greater than the outbound degree, we connect this edge to the T side. The traffic is (inbound-outbound)/2.
Next we can run the maximum stream again.
If the figure is full, it indicates that there is an Euler loop. Otherwise, it does not exist.
CODE:
[Cpp] view plaincopyprint?
# Include <iostream>
# Include <cstdio>
# Include <algorithm>
# Include <string>
# Include <cmath>
# Include <cstring>
# Include <queue>
# Include <set>
# Include <vector>
# Include <stack>
# Include <map>
# Include <iomanip>
# Define PI acos (-1.0)
# Deprecision Max 2505
# Define inf 1 <28
# Define LL (x) (x <1)
# Define RR (x) (x <1 | 1)
# Define REP (I, s, t) for (int I = (s); I <= (t); ++ I)
# Define ll long
# Define mem (a, B) memset (a, B, sizeof ())
# Define mp (a, B) make_pair (a, B)
# Define PII pair <int, int>
Using namespace std;
Inline void RD (int & ret ){
Char c;
Do {
C = getchar ();
} While (c <'0' | c> '9 ');
Ret = c-'0 ';
While (c = getchar ()> = '0' & c <= '9 ')
Ret = ret * 10 + (c-'0 ');
}
Inline void OT (int ){
If (a> = 10) OT (a/10 );
Putchar (a % 10 + '0 ');
}
# Define N 1005
# Define M 100005
Struct ed {
Int s, e, flag;
} Road [M];
Int in [N], out [N];
Struct kdq {
Int e, next, c;
} Ed [M];
Int head [N], num;
Void add (int s, int e, int c ){
Ed [num]. e = e;
Ed [num]. c = c;
Ed [num]. next = head [s];
Head [s] = num ++;
Ed [num]. e = s;
Ed [num]. c = 0;
Ed [num]. next = head [e];
Head [e] = num ++;
}
Void init (){
Mem (head,-1 );
Mem (in, 0 );
Mem (out, 0 );
}
Int S, T;
Int dis [N], qe [M], deep [N];
Int n, m;
/*** Dinic template ***/
Int dinic_bfs (){
Mem (deep,-1 );
Deep [S] = 0;
Int h = 0, t = 0;
Qe [h ++] = S;
While (h> t ){
Int tt = qe [t ++];
For (int I = head [tt]; ~ I; I = ed [I]. next ){
Int e = ed [I]. e;
Int c = ed [I]. c;
If (c> 0 & deep [e] =-1 ){
Deep [e] = deep [tt] + 1;
Qe [h ++] = e;
}
}
}
Return deep [T]! =-1;
}
Int dinic_dfs (int now, int f ){
If (now = T) return f;
Int flow = 0;
For (int I = head [now]; ~ I; I = ed [I]. next ){
Int e = ed [I]. e;
Int c = ed [I]. c;
If (f-flow)> 0 & c> 0 & deep [e] = deep [now] + 1 ){
Int mm = min (f-flow, c );
Int nn = dinic_dfs (e, mm );
Flow + = nn;
Ed [I]. c-= nn;
Ed [I ^ 1]. c + = nn;
}
}
If (flow = 0) deep [now] =-2;
Return flow;
}
Int dinic (){
Int MaxFlow = 0;
While (dinic_bfs ()){
MaxFlow + = dinic_dfs (S, inf );
}
Return MaxFlow;
}
/******/
Int main (){
Int t;
Cin> t;
While (t --){
Cin> n> m;
Init ();
S = 0, T = n + 1;
For (int I = 1; I <= m; I ++ ){
RD (road [I]. s); RD (road [I]. e); RD (road [I]. flag );
Out [road [I]. s] ++;
In [road [I]. e] ++;
}
Bool flag = 0;
For (int I = 1; I <= n; I ++ ){
If (abs (in [I]-out [I]) & 1) {// points with an odd degree difference
Puts ("impossible ");
Flag = 1;
Break;
}
}
If (flag) continue;
For (int I = 1; I <= m; I ++ ){
If (road [I]. flag) continue;
Add (road [I]. s, road [I]. e, 1); // The initial fixed edge is in the direction of a-> B.
}
Int MF = 0;
For (int I = 1; I <= n; I ++ ){
If (out [I]> in [I]) {
Add (S, I, (out [I]-in [I])/2 );
MF + = (out [I]-in [I])/2;
}
Else if (in [I]> out [I]) {
Add (I, T, (in [I]-out [I])/2 );
}
}
Int MaxFlow = dinic ();
If (MaxFlow = MF ){
Puts ("possible ");
}
Else puts ("impossible ");
}
Return 0;
}
# Include <iostream>
# Include <cstdio>
# Include <algorithm>
# Include <string>
# Include <cmath>
# Include <cstring>
# Include <queue>
# Include <set>
# Include <vector>
# Include <stack>
# Include <map>
# Include <iomanip>
# Define PI acos (-1.0)
# Deprecision Max 2505
# Define inf 1 <28
# Define LL (x) (x <1)
# Define RR (x) (x <1 | 1)
# Define REP (I, s, t) for (int I = (s); I <= (t); ++ I)
# Define ll long
# Define mem (a, B) memset (a, B, sizeof ())
# Define mp (a, B) make_pair (a, B)
# Define PII pair <int, int>
Using namespace std;
Inline void RD (int & ret ){
Char c;
Do {
C = getchar ();
} While (c <'0' | c> '9 ');
Ret = c-'0 ';
While (c = getchar ()> = '0' & c <= '9 ')
Ret = ret * 10 + (c-'0 ');
}
Inline void OT (int ){
If (a> = 10) OT (a/10 );
Putchar (a % 10 + '0 ');
}
# Define N 1005
# Define M 100005
Struct ed {
Int s, e, flag;
} Road [M];
Int in [N], out [N];
Struct kdq {
Int e, next, c;
} Ed [M];
Int head [N], num;
Void add (int s, int e, int c ){
Ed [num]. e = e;
Ed [num]. c = c;
Ed [num]. next = head [s];
Head [s] = num ++;
Ed [num]. e = s;
Ed [num]. c = 0;
Ed [num]. next = head [e];
Head [e] = num ++;
}
Void init (){
Mem (head,-1 );
Mem (in, 0 );
Mem (out, 0 );
}
Int S, T;
Int dis [N], qe [M], deep [N];
Int n, m;
/*** Dinic template ***/
Int dinic_bfs (){
Mem (deep,-1 );
Deep [S] = 0;
Int h = 0, t = 0;
Qe [h ++] = S;
While (h> t ){
Int tt = qe [t ++];
For (int I = head [tt]; ~ I; I = ed [I]. next ){
Int e = ed [I]. e;
Int c = ed [I]. c;
If (c> 0 & deep [e] =-1 ){
Deep [e] = deep [tt] + 1;
Qe [h ++] = e;
}
}
}
Return deep [T]! =-1;
}
Int dinic_dfs (int now, int f ){
If (now = T) return f;
Int flow = 0;
For (int I = head [now]; ~ I; I = ed [I]. next ){
Int e = ed [I]. e;
Int c = ed [I]. c;
If (f-flow)> 0 & c> 0 & deep [e] = deep [now] + 1 ){
Int mm = min (f-flow, c );
Int nn = dinic_dfs (e, mm );
Flow + = nn;
Ed [I]. c-= nn;
Ed [I ^ 1]. c + = nn;
}
}
If (flow = 0) deep [now] =-2;
Return flow;
}
Int dinic (){
Int MaxFlow = 0;
While (dinic_bfs ()){
MaxFlow + = dinic_dfs (S, inf );
}
Return MaxFlow;
}
/******/
Int main (){
Int t;
Cin> t;
While (t --){
Cin> n> m;
Init ();
S = 0, T = n + 1;
For (int I = 1; I <= m; I ++ ){
RD (road [I]. s); RD (road [I]. e); RD (road [I]. flag );
Out [road [I]. s] ++;
In [road [I]. e] ++;
}
Bool flag = 0;
For (int I = 1; I <= n; I ++ ){
If (abs (in [I]-out [I]) & 1) {// points with an odd degree difference
Puts ("impossible ");
Flag = 1;
Break;
}
}
If (flag) continue;
For (int I = 1; I <= m; I ++ ){
If (road [I]. flag) continue;
Add (road [I]. s, road [I]. e, 1); // The initial fixed edge is in the direction of a-> B.
}
Int MF = 0;
For (int I = 1; I <= n; I ++ ){
If (out [I]> in [I]) {
Add (S, I, (out [I]-in [I])/2 );
MF + = (out [I]-in [I])/2;
}
Else if (in [I]> out [I]) {
Add (I, T, (in [I]-out [I])/2 );
}
}
Int MaxFlow = dinic ();
If (MaxFlow = MF ){
Puts ("possible ");
}
Else puts ("impossible ");
}
Return 0;
}