题目大意:给一个图,图中有单向边,双向边。问,是否存在欧拉回路。即,混合图欧拉回路。
直接说怎么做吧,对于点i,记dd[i] == 入度-出度。显然,对于每个点,dd[i]必须是2的倍数,否则一定不存在欧拉回路。构图,将双向边随便定向,容量为1。对于dd[i]<0的,建立一条从源点(s)到 i 的容量为-dd[i]/2的边;对于dd[i]>0的,建立一条 i 到 汇点(t)的容量为dd[i]/2的边。如果满流(最大流==与源点相连的边的容量和),则存在欧拉回路。
证明,感觉不好证。反正自己YY了下,把残余网络中,残量为0的边取反(相对最开始的图),感觉这个图,就能是欧拉回路。
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<cctype>
#include<string>
#include<algorithm>
#include<iostream>
#include<ctime>
#include<map>
#include<set>
using namespace std;
#define MP(x,y) make_pair((x),(y))
#define PB(x) push_back(x)
typedef __int64 LL;
//typedef unsigned __int64 ULL;
/* ****************** */
const int INF=1000111222;
const double INFF=1e200;
const double eps=1e-8;
const int mod=1000000007;
const int NN=205;
const int MM=4010;
/* ****************** */
struct G
{
int v,cap,next;
}E[MM];
int p[NN],T,temp_p[NN];
int qw[NN],d[NN];
int dd[NN];
void add(int u,int v,int f)
{
E[T].v=v;
E[T].cap=f;
E[T].next=p[u];
p[u]=T++;
E[T].v=u;
E[T].cap=0;
E[T].next=p[v];
p[v]=T++;
}
bool find_path(int st,int en,int n)
{
int i,u,v,head,tail;
for(i=0;i<=n;i++)
d[i]=-1;
head=tail=0;
d[st]=0;
qw[tail]=st;
while(head<=tail)
{
u=qw[head++];
for(i=p[u];i+1;i=E[i].next)
{
v=E[i].v;
if(d[v]==-1 && E[i].cap>0)
{
d[v]=d[u]+1;
qw[++tail]=v;
}
}
}
return (d[en]!=-1);
}
int dfs_flow(int u,int& en,int f)
{
if(u==en || f==0)
return f;
int flow=0,temp;
for(; temp_p[u]+1 ; temp_p[u]=E[ temp_p[u] ].next )
{
G& e=E[temp_p[u]];
if(d[u]+1==d[e.v])
{
temp=dfs_flow( e.v , en , min(f,e.cap) );
if(temp>0)
{
e.cap-=temp;
E[ temp_p[u]^1 ].cap+=temp;
flow+=temp;
f-=temp;
if(f==0)
break;
}
}
}
return flow;
}
int dinic(int st,int en,int n)
{
int i,ans=0;
while( find_path(st,en,n) )
{
for(i=0;i<=n;i++)
temp_p[i]=p[i];
ans+=dfs_flow(st,en,INF);
}
return ans;
}
int main()
{
int n,m,cas;
int i,x,y,k,sum;
bool fg;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
memset(p,-1,sizeof(p));
T=0;
memset(dd,0,sizeof(dd));
while(m--)
{
scanf("%d%d%d",&x,&y,&k);
dd[y]++;
dd[x]--;
if(k==0)
{
add(x,y,1);
}
}
fg=true;
sum=0;
for(i=1;i<=n;i++)
{
if(dd[i]%2!=0)
{
fg=false;
}
if(dd[i]<0)
{
add(0,i,-dd[i]/2);
sum+=-dd[i]/2;
}
else
{
add(i,n+1,dd[i]/2);
}
}
if(fg && sum!=dinic(0,n+1,n+1))
fg=false;
if(fg)
puts("possible");
else
puts("impossible");
}
return 0;
}