首先二分答案。。。然后这张图变成了有一些有向边,有一些无向边

然后就是混合图欧拉回路的判断

我们知道如果是有向图,它存在欧拉回路的等价条件是所有点的出度等于入度

对于混合图。。。先不管有向边,把无向边随意定向

首先要满足条件就是当前图的点的度数都是偶数,因为把一条边反向端点的出度入度之差改变了2,奇偶性不变

我们只要判断是否把部分已经定向的无向边反向以后可以满足度都是偶数这个条件

用网络流来判断

对于每条边,如果定向为$x$到$y$,则$y$向$x$连边,流量为1

对于每个点$x$,如果出度 - 入度大于0,源点向$x$连边,否则$x$向汇点连边,流量为度数差除以2

如果满流则说明可以

 

  1 /**************************************************************
  2     Problem: 2095
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:136 ms
  7     Memory:952 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13  
 14 using namespace std;
 15 const int N = 1e3 + 5;
 16 const int M = 2e3 + 5;
 17 const int inf = 1e9;
 18  
 19 inline int read();
 20  
 21 struct Edge {
 22     int x, y;
 23     int v1, v2;
 24      
 25     inline void get() {
 26         x = read(), y = read(), v1 = read(), v2 = read();
 27         if (v1 > v2) swap(x, y), swap(v1, v2);
 28     }
 29 } E[M];
 30  
 31 struct edge {
 32     int next, to, f;
 33     edge() {}
 34     edge(int _n, int _t, int _f) : next(_n), to(_t), f(_f) {}
 35 } e[M << 2];
 36  
 37 int n, m, S, T;
 38 int first[N], tot;
 39 int deg[N], tot_deg;
 40 int d[N];
 41  
 42 inline void Add_Edges(int x, int y, int f) {
 43     e[++tot] = edge(first[x], y, f), first[x] = tot;
 44     e[++tot] = edge(first[y], x, 0), first[y] = tot;
 45 }
 46  
 47 #define y e[x].to
 48 #define p q[l]
 49 bool bfs() {
 50     static int l, r, x, q[N];
 51     memset(d, -1, sizeof(d));
 52     d[q[1] = S] = 1;
 53     for (l = r = 1; l != r + 1; ++l)
 54         for (x = first[p]; x; x = e[x].next)
 55             if (!~d[y] && e[x].f) {
 56                 d[q[++r] = y] = d[p] + 1;
 57                 if (y == T) return 1;
 58             }
 59     return 0;
 60 }
 61 #undef p
 62  
 63 int dfs(int p, int lim) {
 64   if (p == T || !lim) return lim;
 65   int x, tmp, rest = lim;
 66   for (x = first[p]; x && rest; x = e[x].next) 
 67     if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) {
 68       rest -= (tmp = dfs(y, tmp));
 69       e[x].f -= tmp, e[x ^ 1].f += tmp;
 70       if (!rest) return lim;
 71     }
 72   if (rest) d[p] = -1;
 73   return lim - rest;
 74 }
 75 #undef y
 76  
 77 int Dinic() {
 78   static int res, i;
 79   for (res = 0, i = 1; i <= n; ++i)
 80         if (deg[i] & 1) return -1;
 81   while (bfs())
 82     res += dfs(S, inf);
 83   return res;
 84 }
 85  
 86 void rebuild_graph(int t) {
 87     static int i;
 88     tot = 1, tot_deg = 0;
 89     for (i = 1; i <= n + 2; ++i)
 90         deg[i] = first[i] = 0;
 91     for (i = 1; i <= m; ++i) {
 92         if (E[i].v1 <= t) --deg[E[i].x], ++deg[E[i].y];
 93         if (E[i].v2 <= t) Add_Edges(E[i].y, E[i].x, 1);
 94     }
 95     for (i = 1; i <= n; ++i)
 96         if (deg[i] > 0) tot_deg += deg[i] >> 1, Add_Edges(S, i, deg[i] >> 1);
 97         else Add_Edges(i, T, (-deg[i]) >> 1);
 98 }
 99  
100 int main() {
101     int i, l = inf, r = 0, tmp;
102     n = read(), m = read(), S = n + 1, T = S + 1;
103     for (i = 1; i <= m; ++i) {
104         E[i].get();
105         l = min(l, E[i].v1), r = max(r, E[i].v2);
106     }
107     l -= 1, tmp = (r += 1);
108 #define mid (l + r >> 1)
109     while (l + 1 < r) {
110         rebuild_graph(mid);
111         if (Dinic() == tot_deg) r = mid;
112         else l = mid;
113     }
114 #undef mid
115     if (tmp == r) puts("NIE");
116     else printf("%d\n", r);
117     return 0;
118 }
119  
120 inline int read() {
121     static int x;
122     static char ch;
123     x = 0, ch = getchar();
124     while (ch < '0' || '9' < ch)
125         ch = getchar();
126     while ('0' <= ch && ch <= '9') {
127         x = x * 10 + ch - '0';
128         ch = getchar();
129     }
130     return x;
131 }
View Code

 

posted on 2015-05-16 23:21  Xs酱~  阅读(447)  评论(0编辑  收藏  举报