首先二分答案。。。然后这张图变成了有一些有向边,有一些无向边
然后就是混合图欧拉回路的判断
我们知道如果是有向图,它存在欧拉回路的等价条件是所有点的出度等于入度
对于混合图。。。先不管有向边,把无向边随意定向
首先要满足条件就是当前图的点的度数都是偶数,因为把一条边反向端点的出度入度之差改变了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 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen