关于混合图欧拉回路可以参考这篇文章:
http://blog.csdn.net/xsbailong/article/details/6965443
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <queue>
#include <limits.h>
using namespace std;
const int maxn = 2010;
int ind[205], oud[205], fa[205], g[205][205], n, m;
void init(){
memset(ind, 0, sizeof(ind));
memset(oud, 0, sizeof(oud));
}
bool bfs(int s, int e){
memset(fa, -1, sizeof(fa));
queue<int> q;
q.push(s);
while (q.size()){
int u = q.front();q.pop();
if(u == e)return true;
for(int i = 0 ; i <= e; ++i){
if(g[u][i] && fa[i] < 0){
fa[i] = u;
q.push(i);
}
}
}
return false;
}
int EK(int s, int e){
int flow = 0;
while (bfs(s, e)){
int minFlow = INT_MAX;
for (int i = e; i != 0; i = fa[i]){
if(g[fa[i]][i] < minFlow){
minFlow = g[fa[i]][i];
}
}
for (int i = e; i != 0; i = fa[i]){
g[fa[i]][i] -= minFlow;
g[i][fa[i]] += minFlow;
}
flow += minFlow;
}
return flow;
}
int main(){
int T;
scanf("%d", &T);
while (T--){
init();
scanf("%d%d", &n, &m);
int eidx = 0, f = 0, flow = 0;
memset(g, 0, sizeof(g));
for (int i = 0; i < m; ++i){
int u, v, p;
scanf("%d%d%d", &u, &v, &p);
if(p == 0)g[u][v]++;
ind[v]++;
oud[u]++;
}
for (int i = 1; i <= n; ++i){
if((ind[i] - oud[i]) % 2){ //出入度之和为奇数,不可能是欧拉回路
f = 1;
break;
}
if(ind[i] > oud[i]){ //入度大于出度, 和汇点连边,相当于把多出来的边反向
g[i][n + 1] += (ind[i] - oud[i]) / 2;
}else{ //出度大于入度, 和源点连边,相当于把多出来的边反向
g[0][i] += (oud[i] - ind[i]) / 2;
flow += (oud[i] - ind[i]) / 2;//累加流值
}
}
if(f){
printf("impossible\n");
continue;
}
int res = EK(0, n + 1);
if(res != flow){
printf("impossible\n");
}else{
printf("possible\n");
}
}
return 0;
}