1. 程式人生 > >POJ 1637:Sightseeing tour

POJ 1637:Sightseeing tour

cit return script () exactly != pos queue ==

Description

The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can see every corner of the beautiful city. They want to construct the tour so that every street in the city is visited exactly once. The bus should also start and end at the same junction. As in any city, the streets are either one-way or two-way, traffic rules that must be obeyed by the tour bus. Help the executive board and determine if it‘s possible to construct a sightseeing tour under these constraints.

Translation

判斷混合圖是否存在歐拉回路,混合圖即 既存在單向邊也存在雙向邊的圖

Solution

其實決策就是把雙向邊定向
假設我們隨便定好項,會得到一個入度和出度,設其差值為 \(in[i]\)
如果不是偶數顯然不存在
否則就要調整雙向邊的方向,存在歐拉回路當且僅當所有點都滿足 \(in[i]==0\)

我們把 \(in[i]\) 為負數的連到 \(S\),容量為 \(-\frac{in[i]}{2}\),正數的連到 \(T\),容量為 \(\frac{in[i]}{2}\)
一條\(S->T\)的增廣路相當於把左邊的點 \(in[i]+=2\),右邊的 \(in[i]-=2\)


如果全部流滿則代表存在

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N=405,M=100005,inf=2e8;
int n,m,head[N],nxt[M],to[M],dis[M],num=1,in[N];
inline void link(int x,int y,int z){
    nxt[++num]=head[x];to[num]=y;head[x]=num;dis[num]=z;
    nxt[++num]=head[y];to[num]=x;head[y]=num;dis[num]=0
; } int S,T=N-1,dep[N]; inline bool bfs(){ queue<int>q; memset(dep,0,sizeof(dep)); q.push(S);dep[S]=1; while(!q.empty()){ int x=q.front();q.pop(); for(int i=head[x];i;i=nxt[i]){ int u=to[i]; if(dis[i]<=0 || dep[u])continue; dep[u]=dep[x]+1;q.push(u); } } return dep[T]; } inline int dfs(int x,int flow){ if(x==T || !flow)return flow; int tot=0,u,t; for(int i=head[x];i;i=nxt[i]){ u=to[i]; if(dep[u]!=dep[x]+1 || dis[i]<=0)continue; t=dfs(u,min(flow,dis[i])); dis[i]-=t;dis[i^1]+=t; flow-=t;tot+=t; if(!flow)break; } if(!tot)dep[x]=-1; return tot; } inline int Dinic(){ int tmp,tot=0; while(bfs()){ tmp=dfs(S,inf); while(tmp)tot+=tmp,tmp=dfs(S,inf); } return tot; } inline void Clear(){ num=1; for(register int i=0;i<N;i++)head[i]=in[i]=0; } void work(){ Clear(); int x,y,z,tot=0; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); in[y]++,in[x]--; if(!z)link(x,y,1); } for(int i=1;i<=n;i++)if(in[i]&1){puts("impossible");return ;} for(int i=1;i<=n;i++){ if(in[i]<0)link(S,i,-(in[i]>>1)); else if(in[i]>0)link(i,T,in[i]>>1),tot+=in[i]>>1; } if(Dinic()==tot)puts("possible"); else puts("impossible"); } int main(){ freopen("pp.in","r",stdin); freopen("pp.out","w",stdout); int T;cin>>T; while(T--)work(); return 0; }

POJ 1637:Sightseeing tour