欧拉回路判断方法
膜板题
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n,m,u,v;
int in[210],out[210];
int dis[210],gap[210];
int sum_src,sum_sik;
struct edge {
int v,f,next;
}e[3010];
int cnt,head[210];
int read_int () {
char c = getchar();
int re = 0;
for(;c > '9' || c < '0';c = getchar());
for(;c >= '0' && c <= '9';c = getchar())
re = re * 10 + c - '0';
return re;
}
void adde (int u,int v,int f) {
e[cnt].v = v;
e[cnt].f = f;
e[cnt].next = head[u];
head[u] = cnt++;
e[cnt].v = u;
e[cnt].f = 0;
e[cnt].next = head[v];
head[v] = cnt++;
}
int dfs (int u,int minf) {
if(u == n + 1)
return minf;
int chan = n + 1,leftf = minf;
for(int i = head[u];i != -1;i = e[i].next) {
int v = e[i].v;
if(e[i].f > 0) {
if(dis[v] + 1 == dis[u]) {
int t = dfs(v,min(leftf,e[i].f));
e[i].f -= t;
e[i ^ 1].f += t;
leftf -= t;
if(dis[0] >= n + 2)
return minf - leftf;
if(leftf == 0)
break;
}
chan = min(chan,dis[v]);
}
}
if(leftf == minf) {
if(--gap[dis[u]] == 0)
dis[0] = n + 2;
++gap[dis[u] = chan + 1];
}
return minf - leftf;
}
bool sap () {
int re = 0;
gap[0] = n + 2;
while(dis[0] < n + 2)
re += dfs(0,0x3f3f3f3f);
if(re == sum_src && re == sum_sik)
return 1;
return 0;
}
int main () {
int T = read_int();
while(T--) {
memset(head,-1,sizeof head);
memset(in,0,sizeof in);
memset(out,0,sizeof out);
memset(dis,0,sizeof dis);
memset(gap,0,sizeof gap);
sum_src = sum_sik = cnt = 0;
n = read_int();
m = read_int();
for(int i = 1;i <= m;++i) {
u = read_int();
v = read_int();
if(!read_int())
adde(u,v,1);
++in[v];
++out[u];
}
bool f = 0;
for(int i = 1;i <= n;++i) {
if((int)abs(out[i] - in[i]) & 1 || (in[i] == 0 && out[i] == 0)) {
f = 1;
break;
}
if(out[i] - in[i] > 0) {
adde(0,i,(out[i] - in[i]) >> 1);
sum_src += (out[i] - in[i]) >> 1;
}
if(out[i] - in[i] < 0) {
adde(i,n + 1,(in[i] - out[i]) >> 1);
sum_sik += (in[i] - out[i]) >> 1;
}
}
if(f) {
printf("impossible\n");
continue;
}
if(sap())
printf("possible\n");
else printf("impossible\n");
}
}