。。。。对拍了好久,对出个300多个遍的bug,正在纠结要不要看的时候。。突然发现。。哪错了。。边权是1 。。但你也不能就赋1啊。。你个白痴T,T。。
对于无向边,随便定向,然后看看每个点的出入度之差是不是偶数,如果有不是的那就不是欧拉图了,如果都是,那么对于之差为偶的点,改变x/2 (x为出入度之差)条边,如果是满流,那么就能变成欧拉回路。如果不是满流,就不能变成欧拉回路。
建图:将入度>出度的点与vt相连,边权值为x,将入度<出度的点与vs相连,边权值为x,对于每条边权值都为1.(但要加加加啊。。)
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<cstdlib>
#define MX 1000000
using namespace std;
int m,s,in[400],out[400],cas,map[400][400],d[400];
struct edge{
int u,v;
}eg[2005];
int min(int a,int b){
return a<b?a:b;
}
bool bfs(){
int queue[10000],qs=0,qe=1;
queue[qs]=0;
memset(d,-1,sizeof(d));
d[0]=0;
while(qs<qe){
int v=queue[qs++];
for(int i=0;i<=m+1;i++){
if(d[i]==-1&&map[v][i]){
d[i]=d[v]+1;
queue[qe++]=i;
}
}
}
if(d[m+1]==-1)return false;
return true;
}
int dfs(int start,int sum){
if(start==m+1){
return sum;
}
int sumcy=sum;
for(int i=0;i<=m+1;i++){
if(map[start][i]&&d[i]==d[start]+1){
int t=dfs(i,min(map[start][i],sum));
map[start][i]-=t;
map[i][start]+=t;
sum-=t;
}
}
return sumcy-sum;
}
int main(){
scanf("%d",&cas);
while(cas--){
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(map,0,sizeof(map));
scanf("%d%d",&m,&s);
int k=0;
for(int i=0;i<s;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a==b)continue;
if(c!=1){
eg[k].u=a;
eg[k++].v=b;
}
out[a]++;
in[b]++;
}
//printf("!\n");
bool flag=true;
int sum=0;
for(int i=1;i<=m;i++){
int p=out[i]-in[i];
if((abs(p))%2){
flag=false;
// printf("!\n");
break;
}
else {
if(out[i]-in[i]>0){
map[0][i]+=(out[i]-in[i])/2;
sum+=(out[i]-in[i])/2;
}
else {
map[i][m+1]+=(in[i]-out[i])/2;
}
}
}
if(!flag){
printf("impossible\n");
continue;
}
for(int i=0;i<k;i++){
map[eg[i].u][eg[i].v]+=1;
}
// for(int i=0;i<=m+1;i++){
// for(int j=0;j<=m+1;j++){
// printf("%d ",map[i][j]);
// }
// printf("\n");
// }
int ans=0;
while(bfs()){
ans+=dfs(0,MX);
}
// for(int i=1;i<=m;i++){
// if(map[0][i]){
// flag=false;
// break;
// }
// }
if(sum==ans){
flag=true;
}
else flag=false;
if(flag){
printf("possible\n");
}
else{
printf("impossible\n");
}
}
return 0;
}