Sightseeing tour(混合图的欧拉回路是否存在)
rt
首先,我们将无向路强制转化为有向路,并将其建图(流量为1)
相当于你先搞成有向图,先判一遍(abs(in[i]]-out[i]))%2
然后,我们分别找出in[i]>out[i]&&in[i]<out[i]的点
将其分别与t,s,建边(流量为差值减一)
以为将其中某些路径反向,以得到满流;
当然如果结果未满流,则也不可能
#include<iostream> #include<queue> #define re return #define R register #define ll long long #define inc(i,l,r) for(register int i=l;i<=r;++i) const int maxn=100005,maxm=2000005; using namespace std; char buf[1<<21],*p1,*p2; inline int gc(){re p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;} template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } int n,m,k=1,cnt=0,s,t; int hd[maxn],in[maxn],out[maxn],cur[maxn]; int deep[maxn]; struct node{ int to,nt,flow; }e[maxm]; inline void add(int x,int y,int f) { e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].flow=f; e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].flow=0; } inline bool bfs() { queue<int>q; inc(i,s,t)deep[i]=0; deep[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=hd[u];i;i=e[i].nt) { int v=e[i].to; if(!deep[v]&&e[i].flow) { deep[v]=deep[u]+1; if(v==t)re 1; q.push(v); } } } re 0; } inline int dfs(int x,int flow) { if(x==t)re flow; int delta=flow; for(int& i=cur[x];i;i=e[i].nt) { int v=e[i].to; if(deep[v]==deep[x]+1&&e[i].flow) { int d=dfs(v,min(delta,e[i].flow)); e[i].flow-=d; e[i^1].flow+=d; delta-=d; if(!delta)re flow; } } re flow-delta; } int main() { int T,x,y,z; rd(T); while(T--) { int falg=0,ans=0; rd(n),rd(m); k=1;s=0;t=n+1; inc(i,s,t)hd[i]=in[i]=out[i]=0; inc(i,1,m) { rd(x),rd(y),rd(z); if(!z)add(x,y,1); ++out[x];++in[y]; } inc(i,1,n) { int x=in[i]-out[i]; if(x%2) { falg=1; break; } else if(x>0) { add(i,t,x>>1); ans+=(x>>1); } else add(s,i,(-x)>>1); } if(falg)printf("impossible\n"); else { int ret=0; while(bfs()) { inc(i,s,t)cur[i]=hd[i]; ret+=dfs(s,ans); } if(ret==ans)printf("possible\n"); else printf("impossible\n"); } } re 0; }