poj1637 Sightseeing tour 混合图欧拉回路判定

  传送门

第一次做这种题, 尽管ac了但是完全不知道为什么这么做。

题目就是给一些边, 有向边与无向边混合, 问你是否存在欧拉回路。

做法是先对每个点求入度和出度, 如果一条边是无向边, 就随便指定一个方向, 然后连一条边, 权值为1。 最后统计入度出度, 如果一个点的(入度-出度)%2==1, 就说明不存在欧拉回路。 如果全都满足, 就判断每个点的入度出度的大小关系, 入度>出度, 就向汇点连一条边, 权值为(入度-出度)/2, 相反的话就向源点连边。

跑一遍最大流, 看是否满流, 如果满流就说明存在。

完全不理解.....还是太弱。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define pb(x) push_back(x)
  4 #define ll long long
  5 #define mk(x, y) make_pair(x, y)
  6 #define lson l, m, rt<<1
  7 #define mem(a) memset(a, 0, sizeof(a))
  8 #define rson m+1, r, rt<<1|1
  9 #define mem1(a) memset(a, -1, sizeof(a))
 10 #define mem2(a) memset(a, 0x3f, sizeof(a))
 11 #define rep(i, a, n) for(int i = a; i<n; i++)
 12 #define ull unsigned long long
 13 typedef pair<int, int> pll;
 14 const double PI = acos(-1.0);
 15 const double eps = 1e-8;
 16 const int mod = 1e9+7;
 17 const int inf = 1061109567;
 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 19 const int maxn = 210;
 20 const int maxE = 10005;
 21 int indeg[maxn], outdeg[maxn];
 22 int head[maxE], s, t, num, q[maxE], dis[maxn];
 23 struct node
 24 {
 25     int to, nextt, c;
 26 }e[maxE];
 27 void init() {
 28     mem1(head);
 29     num = 0;
 30     mem(indeg);
 31     mem(outdeg);
 32 }
 33 void add(int u, int v, int c) {
 34     e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++;
 35     e[num].to = u; e[num].nextt = head[v]; e[num].c = 0; head[v] = num++;
 36 }
 37 int bfs() {
 38     mem(dis);
 39     int st = 0, ed = 0;
 40     q[ed++] = s;
 41     dis[s] = 1;
 42     while(st<ed) {
 43         int u = q[st++];
 44         for(int i = head[u]; ~i; i = e[i].nextt) {
 45             int v = e[i].to;
 46             if(e[i].c&&!dis[v]) {
 47                 dis[v] = dis[u]+1;
 48                 if(v == t)
 49                     return 1;
 50                 q[ed++] = v;
 51             }
 52         }
 53     }
 54     return 0;
 55 }
 56 int dfs(int u, int limit) {
 57     if(u == t)
 58         return limit;
 59     int cost = 0;
 60     for(int i = head[u]; ~i; i = e[i].nextt) {
 61         int v = e[i].to;
 62         if(e[i].c&&dis[v] == dis[u]+1) {
 63             int tmp = dfs(v, min(limit-cost, e[i].c));
 64             if(tmp>0) {
 65                 e[i].c -= tmp;
 66                 e[i^1].c += tmp;
 67                 cost += tmp;
 68                 if(limit == cost)
 69                     break;
 70             } else {
 71                 dis[v] = -1;
 72             }
 73         }
 74     }
 75     return cost;
 76 }
 77 int dinic() {
 78     int ans = 0;
 79     while(bfs()) {
 80         ans += dfs(s, inf);
 81     }
 82     return ans;
 83 }
 84 int main()
 85 {
 86     int T, n, m, x, y, z;
 87     cin>>T;
 88     while(T--) {
 89         scanf("%d%d", &n, &m);
 90         init();
 91         s = 0, t = n+1;
 92         while(m--) {
 93             scanf("%d%d%d", &x, &y, &z);
 94             indeg[y]++;
 95             outdeg[x]++;
 96             if(z == 0) {
 97                 add(x, y, 1);
 98             }
 99         }
100         int flag = 0;
101         for(int i = 1; i<=n; i++) {
102             if(abs(indeg[i]-outdeg[i])%2==1) {
103                 flag = 1;
104                 break;
105             }
106         }
107         if(flag) {
108             cout<<"impossible"<<endl;
109             continue;
110         }
111         int sum = 0;
112         for(int i = 1; i<=n; i++) {
113             if(indeg[i]<outdeg[i]) {
114                 add(s, i, (outdeg[i]-indeg[i])/2);
115             } else {
116                 add(i, t, (indeg[i]-outdeg[i])/2);
117                 sum += (indeg[i]-outdeg[i])/2;
118             }
119         }
120         int ans = dinic();
121         if(ans == sum) {
122             cout<<"possible"<<endl;
123         } else {
124             cout<<"impossible"<<endl;
125         }
126     }
127 }
时间: 2024-08-04 14:13:29

poj1637 Sightseeing tour 混合图欧拉回路判定的相关文章

POJ1637 Sightseeing tour (混合图欧拉回路)(网络流)

Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9100   Accepted: 3830 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 beauti

POJ 1637 Sightseeing tour 混合图欧拉回路存在性判断

没有想到网络流还能解决这一类问题,完全想不到@[email protected] 一开始把所有的无向边制定任意方向有当做有向边看,然后统计每个点的入度和出度.以前有向图的欧拉回路判定是每个点的入读都等于出度,这样可以保证可以回到起点,现在在一些边可以调换方向的情况下,所有定点的入度和出度之差必定为偶数,因为调换任意一条边的方向都会使两个定点的入度和出度变化2,所以要构成一个欧拉回路所有点的入度和出度之差都为偶数,并设差为deg. 现在问题转化成了能否通过改变一些边的方向来是的所有点的入度出度都为

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

http://poj.org/problem?id=1637 Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7498   Accepted: 3123 Description The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can

POJ1637:Sightseeing tour(混合图的欧拉回路)

Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10581   Accepted: 4466 题目链接:http://poj.org/problem?id=1637 Description: The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that touri

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

题目大意:给出一张混合图,问是否存在欧拉回路. 思路:成题,直接看题解吧. http://www.cnblogs.com/Lyush/archive/2013/05/01/3052847.html CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 510 #define M

POJ 1637 Sightseeing tour (混合图欧拉回路)

Sightseeing tour 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 visit

POJ 1637 Sightseeing tour(混合图的欧拉回路)

题目链接 建个图,套个模板. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <algorithm> #include <vector> #include <string> #include <queue> using namespace std; #define INF 0x3ffffff str

poj1637 Sightseeing tour[最大流+欧拉回路]

混合图的欧拉回路定向问题. 顺便瞎说几句,有向图定欧拉回路的充要条件是每个点入度等于出度,并且图联通.无向图的话只要联通无奇点即可. 欧拉路径的确定应该是无向图联通且奇点数0个或2个,有向图忘了,好像复杂一点,这个真考到就暴力瞎搜吧. 既然每个点的度数都定了,又入度等于出度,那两者对半分,在二分图里左向右连上原图的边,左点集与s连容量为待补充的出度,右点集反之.这样如果我真可以定下来的话,就会有左边所有连边都满流.所以跑最大流看能不能到满流(就是差的总出度)即可. 1 #include<iost

【POJ1637】Sightseeing tour 混合图求欧拉回路存在性 网络流、

题意:多组数据,最后的0/1表示0无向1有向. 问是否存在欧拉回路. 题解:无向边给它任意定个向. 首先欧拉回路中点入度=出度. 然后发现每个无向边如果修改个方向,原来的入点的入度+1,出度-1,出点反之. 然后我们不妨对入度和出度不同的点跟源汇中之一连边,容量为入出度差一半(每改一条边差-2) 然后原来的无向边联系图中各点,容量1,最后check if(maxflow==sum差/4). 这都没看懂的弱菜们不妨出度多的连源,入度多的连汇,容量为入出度差一半,然后按无向边的定向给它在网络流图中定