#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define NN 500
#define MM 500000
#define INF 0x7fffffff
using namespace std;
int n,m,S,T,NV,sum;
struct Edge
{
int u,v,flow,next;
} e[MM];
int en,head[NN];
void addedge(int u,int v,int flow)
{
e[en].u=u;
e[en].v=v;
e[en].flow=flow;
e[en].next=head[u];
head[u]=en++;
e[en].u=v;
e[en].v=u;
e[en].flow=0;
e[en].next=head[v];
head[v]=en++;
}
int in[NN],out[NN];
bool init()
{
scanf("%d%d",&n,&m);
S=0;
T=n+1;
NV=T+1;
en=0;
for (int i=0; i<NV; i++)
{
head[i]=-1;
in[i]=out[i]=0;
}
int x,y,d;
for (int i=1; i<=m; i++)
{
scanf("%d%d%d",&x,&y,&d);
if (x==y) continue;
out[x]++;
in[y]++;
if (d!=1) addedge(x,y,1);
}
sum=0;
for (int i=1; i<=n; i++)
{
int degree=out[i]-in[i];
if ((degree%2)) return false;
degree>>=1;
if (degree>0) addedge(S,i,degree),sum+=degree;
else addedge(i,T,-degree);
}
return true;
}
int cur[NN],gap[NN],dis[NN],pre[NN];
int sap()
{
int maxflow=0;
for(int i=0; i<NV; i++)
{
dis[i]=gap[i]=0;
cur[i]=head[i];
}
int u=pre[S]=S;
int aug=INF;
gap[0]=NV;
while(dis[S]<NV)
{
loop:
for(int &i=cur[u]; i!=-1; i=e[i].next)
{
int v=e[i].v;
if(e[i].flow && dis[u]==dis[v]+1)
{
aug=aug<e[i].flow ? aug:e[i].flow;
pre[v]=u;
u=v;
if(v==T)
{
maxflow+=aug;
for(u=pre[u]; v!=S; v=u,u=pre[u])
{
e[cur[u]].flow-=aug;
e[cur[u]^1].flow+=aug;
}
aug=INF;
}
goto loop;
}
}
int min_dis=NV;
for(int i=head[u]; i!=-1; i=e[i].next)
{
int v=e[i].v;
if(e[i].flow && min_dis>dis[v])
{
cur[u]=i;
min_dis=dis[v];
}
}
if(--gap[dis[u]]==0) break;
gap[dis[u]=min_dis+1]++;
u=pre[u];
}
return maxflow;
}
int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
if (!init())
{
printf("impossible\n");
continue;
}
if (sap()==sum) printf("possible\n");
else printf("impossible\n");
}
return 0;
}
POJ1637-最大流判断混合图欧拉回路
最新推荐文章于 2020-10-19 15:39:59 发布