混合欧拉回路poj 1637 Sightseeing tour
把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路;
好了,现在每个点入度和出度之差均为偶数。那么将这个偶数除以2,得x。也就是说,对于每一个点,只要将x条边改变方向(入>出就是变入,出>入就是变出),就能保证出=入。如果每个点都是出=入,那么很明显,该图就存在欧拉回路。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; const int M=205; const int inf=0x3f3f3f3f; inline int read(){ int sum=0,x=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') x=0; ch=getchar(); } while(ch>='0'&&ch<='9') sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar(); return x?sum:-sum; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } struct node{ int v,w,nextt; }e[2005]; int deep[M],cur[M],head[M],du[M],tot,s,t; bool bfs(){ for(int i=0;i<=t;i++) deep[i]=0; queue<int>que; que.push(s); deep[s]=1; while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u];~i;i=e[i].nextt){ int v=e[i].v; if(e[i].w>0&&deep[v]==0){ deep[v]=deep[u]+1; if(v==t){ return true; } que.push(v); } } } return deep[t]==0?false:true; } int dfs(int u,int fl){ if(u==t){ return fl; } int x,ans=0; for(int i=cur[u];~i;i=e[i].nextt){ int v=e[i].v; if(e[i].w>0&&deep[v]==deep[u]+1){ x=dfs(v,min(fl-ans,e[i].w)); e[i].w-=x; e[i^1].w+=x; if(e[i].w) cur[u]=i; ans+=x; if(ans==fl) return ans; } } if(ans==0) deep[u]=0; return ans; } int dinic(){ int ans=0; while(bfs()){ //cout<<ans<<endl; for(int i=0;i<=t;i++) cur[i]=head[i]; ans+=dfs(s,inf); } return ans; } void addedge(int u,int v,int w){ e[tot].v=v; e[tot].w=w; e[tot].nextt=head[u]; head[u]=tot++; e[tot].v=u; e[tot].w=0; e[tot].nextt=head[v]; head[v]=tot++; } void init(){ for(int i=0;i<=t;i++) head[i]=-1,du[i]=0; tot=0; } int main(){ int p=read(); while(p--){ int n=read(),m=read(); s=0,t=n+1; init(); while(m--){ int u=read(),v=read(),op=read(); du[u]++,du[v]--; if(!op) addedge(u,v,1); } //jud int flag=0; for(int i=1;i<=n;i++){ if(du[i]&1){ flag=1; break; } } if(flag){ puts("impossible"); continue; } int sum=0; for(int i=1;i<=n;i++){ if(du[i]<0) addedge(i,t,-du[i]/2); else if(du[i]>0) addedge(s,i,du[i]/2),sum+=du[i]/2; } if(sum!=dinic()) puts("impossible"); else puts("possible"); } return 0; }