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 }
原文地址:https://www.cnblogs.com/yohaha/p/5011399.html