首页 > 代码库 > POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)

POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)

http://poj.org/problem?id=1637

题意:
给出n个点和m条边,这些边有些是单向边,有些是双向边,判断是否能构成欧拉回路。

 

思路:

构成有向图欧拉回路的要求是入度=出度,无向图的要求是所有顶点的度数为偶数。

但不管是那个,顶点的度数若是奇数,那都是不能构成的。

这道题目是非常典型的混合图欧拉回路问题,对于双向边,我们先随便定个向,然后就这样先记录好每个顶点的入度和出度。

如果有顶点的度数为奇数,可以直接得出结论,是不能构成欧拉回路的。

那么,如果都是偶数呢?

因为还会存在入度不等于出度的情况,那么这个时候就要通过改变改变双向边的方向来改变度数。对于每个顶点,如果出度大于入度,那么就将该点与源点相连,容量为(out-in)/2,代表需要改变几条双向边的方向,同理,如果入度大于出度,那么就将该点与汇点相连,容量为(in-out)/2。

那么,顶点之间如何连接呢?

对于双向边,将该两个顶点相连,容量为1,代表这条边可以反向一次

最后,走一遍最大流,如果满流,就说明能够构成欧拉回路。

  1 #include<iostream>  2 #include<algorithm>  3 #include<cstring>  4 #include<cstdio>  5 #include<vector>  6 #include<stack>  7 #include<queue>  8 #include<cmath>  9 #include<map> 10 using namespace std; 11 typedef long long LL; 12 typedef pair<int,int> pll; 13 const int INF=0x3f3f3f3f; 14 const int maxn=1000+5; 15  16 struct Edge 17 { 18     int from,to,cap,flow; 19     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){} 20 }; 21  22 struct Dinic 23 { 24     int n,m,s,t; 25     vector<Edge> edges; 26     vector<int> G[maxn]; 27     bool vis[maxn]; 28     int cur[maxn]; 29     int d[maxn]; 30  31     void init(int n) 32     { 33         this->n=n; 34         for(int i=0;i<n;++i) G[i].clear(); 35         edges.clear(); 36     } 37  38     void AddEdge(int from,int to,int cap) 39     { 40         edges.push_back( Edge(from,to,cap,0) ); 41         edges.push_back( Edge(to,from,0,0) ); 42         m=edges.size(); 43         G[from].push_back(m-2); 44         G[to].push_back(m-1); 45     } 46  47     bool BFS() 48     { 49         queue<int> Q; 50         memset(vis,0,sizeof(vis)); 51         vis[s]=true; 52         d[s]=0; 53         Q.push(s); 54         while(!Q.empty()) 55         { 56             int x=Q.front(); Q.pop(); 57             for(int i=0;i<G[x].size();++i) 58             { 59                 Edge& e=edges[G[x][i]]; 60                 if(!vis[e.to] && e.cap>e.flow) 61                 { 62                     vis[e.to]=true; 63                     d[e.to]=d[x]+1; 64                     Q.push(e.to); 65                 } 66             } 67         } 68         return vis[t]; 69     } 70  71     int DFS(int x,int a) 72     { 73         if(x==t || a==0) return a; 74         int flow=0, f; 75         for(int &i=cur[x];i<G[x].size();++i) 76         { 77             Edge &e=edges[G[x][i]]; 78             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) 79             { 80                 e.flow +=f; 81                 edges[G[x][i]^1].flow -=f; 82                 flow +=f; 83                 a -=f; 84                 if(a==0) break; 85             } 86         } 87         return flow; 88     } 89  90     int Maxflow(int s,int t) 91     { 92         this->s=s; this->t=t; 93         int flow=0; 94         while(BFS()) 95         { 96             memset(cur,0,sizeof(cur)); 97             flow +=DFS(s,INF); 98         } 99         return flow;100     }101 }DC;102 103 int in[maxn],out[maxn];104 int u[maxn],v[maxn],w[maxn];105 int n,m;106 107 int main()108 {109     //freopen("D:\\input.txt","r",stdin);110     int T;111     scanf("%d",&T);112     while(T--)113     {114         scanf("%d%d",&n,&m);115         memset(in,0,sizeof(in));116         memset(out,0,sizeof(out));117         int src=http://www.mamicode.com/0,dst=n+1;118         DC.init(dst+1);119 120         for(int i=1;i<=m;i++)121         {122             scanf("%d%d%d",&u[i],&v[i],&w[i]);123             out[u[i]]++;124             in[v[i]]++;125         }126 127         bool flag=true;128         int full_flow=0;129         for(int i=1;i<=n;i++)130         {131             if(((in[i]+out[i])&1))  {flag=false;break;}132             if(in[i]>out[i])   {DC.AddEdge(i,dst,(in[i]-out[i])/2);full_flow+=(in[i]-out[i])/2;}133             if(out[i]>in[i])   DC.AddEdge(src,i,(out[i]-in[i])/2);134         }135 136         if(flag)137         {138             for(int i=1;i<=m;i++)139                 if(!w[i])  DC.AddEdge(u[i],v[i],1);140         }141 142         if(flag)143         {144             int flow=DC.Maxflow(src,dst);145             if(flow==full_flow)  puts("possible");146             else puts("impossible");147         }148         else puts("impossible");149     }150     return 0;151 }

 

POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)