POJ 1637 Sightseeing tour
Posted NeighThorn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1637 Sightseeing tour相关的知识,希望对你有一定的参考价值。
Sightseeing tour
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 9276 | Accepted: 3924 |
Description
Input
Output
Sample Input
4 5 8 2 1 0 1 3 0 4 1 1 1 5 0 5 4 1 3 4 0 4 2 1 2 2 0 4 4 1 2 1 2 3 0 3 4 0 1 4 1 3 3 1 2 0 2 3 0 3 2 0 3 4 1 2 0 2 3 1 1 2 0 3 2 0
Sample Output
possible impossible impossible possible
Source
题意:
给出一张混合图,询问这张图是否存在欧拉回路(经过每条边一次且仅一次)...
分析:
如果一个有向图存在欧拉回路满足的条件是所有的点in[i]==out[i],所以我们可以先给无向边定向,然后记录每个点的入度和出度,如果存在某一个点的入度和出度差值为奇数,那么这张图一定不存在欧拉回路,因为我们如果要找欧拉回路一定是通过反向无向边来使得每个点的入度等于出度,而每反向一条边,它所连接的两个点的入度和出度差值都改变了2...
那么对于一个入度不等于出度的点,我们需要把和它相邻的abs(in[i]-out[i])/2条边反向,所以对于一个in[i]>out[i]的点我们从i向T连一条容量为(in[i]-out[i])/2的边,对于一个out[i]>in[i]的点我们从S向i连一条容量为(out[i]-in[i])/2的边,然后我们把对于每个无向边,按照初始的定向连边,有向边删去(因为有向边是不能反向的)...如果可以满流就代表当前图满足要求...
代码:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 //by NeighThorn 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 10 const int maxn=200+5,maxm=4000+5; 11 12 int n,m,S,T,cas,cnt,sum,flag,hd[maxn],fl[maxm],to[maxm],in[maxn],out[maxn],nxt[maxm],pos[maxn]; 13 14 inline bool bfs(void){ 15 memset(pos,-1,sizeof(pos)); 16 int head=0,tail=0,q[maxn]; 17 q[0]=S,pos[S]=0; 18 while(head<=tail){ 19 int top=q[head++]; 20 for(int i=hd[top];i!=-1;i=nxt[i]) 21 if(pos[to[i]]==-1&&fl[i]) 22 pos[to[i]]=pos[top]+1,q[++tail]=to[i]; 23 } 24 return pos[T]!=-1; 25 } 26 27 inline int find(int v,int f){ 28 if(v==T) 29 return f; 30 int res=0,t; 31 for(int i=hd[v];i!=-1&&f>res;i=nxt[i]) 32 if(pos[to[i]]==pos[v]+1&&fl[i]) 33 t=find(to[i],min(f-res,fl[i])),res+=t,fl[i]-=t,fl[i^1]+=t; 34 if(!res) 35 pos[v]=-1; 36 return res; 37 } 38 39 inline int dinic(void){ 40 int res=0,t; 41 while(bfs()) 42 while(t=find(S,inf)) 43 res+=t; 44 return res; 45 } 46 47 inline void add(int s,int x,int y){ 48 fl[cnt]=s;to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++; 49 fl[cnt]=0;to[cnt]=x;nxt[cnt]=hd[y];hd[y]=cnt++; 50 } 51 52 signed main(void){ 53 // freopen("in.txt","r",stdin); 54 scanf("%d",&cas); 55 while(cas--){ 56 flag=cnt=sum=0; 57 scanf("%d%d",&n,&m); 58 memset(in,0,sizeof(in)); 59 memset(hd,-1,sizeof(hd)); 60 memset(out,0,sizeof(out)); 61 for(int i=1,s,x,y;i<=m;i++){ 62 scanf("%d%d%d",&x,&y,&s); 63 if(s==0) 64 add(1,x,y); 65 in[y]++,out[x]++; 66 }S=0,T=n+1; 67 for(int i=1;i<=n&&!flag;i++){ 68 if(abs(in[i]-out[i])&1) 69 flag=1; 70 else if(in[i]>out[i]) 71 add((in[i]-out[i])>>1,i,T); 72 else if(out[i]>in[i]) 73 add((out[i]-in[i])>>1,S,i),sum+=(out[i]-in[i])>>1; 74 } 75 if(flag){ 76 puts("impossible");continue; 77 } 78 if(dinic()==sum) 79 puts("possible"); 80 else 81 puts("impossible"); 82 } 83 return 0; 84 }
By NeighThorn
以上是关于POJ 1637 Sightseeing tour的主要内容,如果未能解决你的问题,请参考以下文章
网络流(最大流) POJ 1637 Sightseeing tour
POJ 1637 Sightseeing tour (混合图欧拉回路)
POJ1637:Sightseeing tour(混合图的欧拉回路)
网络流 + 欧拉回路 = B - Sightseeing tour POJ - 1637