传送门
题意:给你一个混合图,问能否从一个点出发经过所有边回到这个点。
思路:一头雾水,借鉴前人博客,现在方法会了,马上吃饭走路时再深入想想为什么可以这样吧。
前人博客
#include<iostream> #include<cstdio> #include<cstring> #define maxn 1<<29 using namespace std; int fst[300],next[3000],node[3000],c[3000],en; int f[3000],in[300],pre[300],lu[300]; int m,n,tt,sum,s,t,q[100000]; bool flag; bool vis[300]; void init() { en=0; flag=0; memset(fst,-1,sizeof(fst)); memset(f,0,sizeof(f)); memset(in,0,sizeof(in)); } void add(int u,int v,int a) { next[en]=fst[u]; fst[u]=en; node[en]=v; c[en]=a; en++; next[en]=fst[v]; fst[v]=en; node[en]=u; c[en]=0; en++; } bool bfs() { memset(vis,0,sizeof(vis)); int front=0,end=0; q[end++]=s; vis[s]=1; while(end>front) { int u=q[front++]; for(int i=fst[u];i!=-1;i=next[i]) { int v=node[i]; if(!vis[v]&&c[i]-f[i]>0) { vis[v]=1; pre[v]=u; lu[v]=i; if(v==t)return true; q[end++]=v; } } } return false; } int ek() { int flow=0; while(bfs()) { int mm=maxn; for(int i=t;i!=s;i=pre[i]) { int v=lu[i]; if(c[v]-f[v]<mm)mm=c[v]-f[v]; } for(int i=t;i!=s;i=pre[i]) { int v=lu[i]; f[v]+=mm; f[v^1]-=mm; } flow+=mm; } return flow; } int main() { int u,v,a; scanf("%d",&tt); while(tt--) { init(); scanf("%d%d",&n,&m); s=0; t=n+1; for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&a); if(!a) { add(u,v,1); } in[v]++; in[u]--; } sum=0; for(int i=1;i<=n;i++) { if(in[i]%2) { flag=1; break; } int co=in[i]/2; if(co>0) { add(i,t,co); sum+=co; } else add(0,i,-co); } if(flag) { cout<<"impossible"<<endl; continue; } if(sum==ek())cout<<"possible"<<endl; else cout<<"impossible"<<endl; } return 0; }