码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-05-29 10:59:57      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:最大流   can   pop   stream   std   ==   add   vector   sizeof   

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=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(混合图欧拉回路+最大流)

标签:最大流   can   pop   stream   std   ==   add   vector   sizeof   

原文地址:http://www.cnblogs.com/zyb993963526/p/6917356.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!