传送门
题解:
本人的欧拉路径专题总结☜戳这里。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN=202,MAXM=1002,INF=0x3f3f3f3f;
int n,m;
int head[MAXN],etot;
struct EDGE {
int v,nxt,r;
}e[MAXM<<1];
int in[MAXN],out[MAXN],dis[MAXN],cur[MAXN],S,T,maxflow,sumflow;
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
inline void adde(int u,int v,int r) {
e[etot].nxt=head[u],e[etot].v=v,e[etot].r=r,head[u]=etot++;
e[etot].nxt=head[v],e[etot].v=u,e[etot].r=0,head[v]=etot++;
}
inline bool bfs() {
queue<int > q;
memset(dis,-1,sizeof(dis));
dis[S]=0,q.push(S);
while (!q.empty()) {
int p=q.front();
q.pop();
for (int i=head[p];~i;i=e[i].nxt) {
int v=e[i].v;
if (dis[v]==-1&&e[i].r>0)
dis[v]=dis[p]+1,q.push(v);
}
}
return ~dis[T];
}
int dfs(int p,int low) {
if (p==T||low==0) return low;
int cost=0,flow;
for (int &i=cur[p];~i;i=e[i].nxt) {
int v=e[i].v;
if (dis[v]==dis[p]+1&&e[i].r>0&&(flow=dfs(v,min(e[i].r,low)))) {
e[i].r-=flow;
e[i^1].r+=flow;
low-=flow;
cost+=flow;
if (low==0) return cost;
}
}
if (low>0) dis[p]=-1;
return cost;
}
int main() {
// freopen("poj 1637.in","r",stdin);
int kase=read();
while (kase--) {
etot=maxflow=sumflow=0;
memset(head,-1,sizeof(head));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
n=read(),m=read(),S=0,T=n+1;
while (m--) {
int u=read(),v=read(),type=read();
++in[v],++out[u];
if (!type) adde(u,v,1);//manually set the direction
}
bool euler=true;
for (int i=1;i<=n;++i) {
int temp=out[i]-in[i];
if (temp&1) {euler=false;break;}
if (temp>0) adde(S,i,temp>>1),sumflow+=(temp>>1);
else if (temp<0) adde(i,T,(-temp)>>1);
}
if (!euler) {puts("impossible");continue;}
while (bfs()) {//Dinic-maxflow
for (int i=S;i<=T;++i) cur[i]=head[i];
int a;
while (a=dfs(S,INF)) maxflow+=a;
}
puts(sumflow^maxflow?"impossible":"possible");
}
return 0;
}