zoukankan      html  css  js  c++  java
  • BZOJ2095 [Poi2010]Bridges

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

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

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

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

    首先要满足条件就是当前图的点的度数都是偶数,因为把一条边反向端点的出度入度之差改变了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
    ", 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
  • 相关阅读:
    单例模式(Singleton)在SQLite操作中的应用
    android中自定義progress
    eclipse中高亮显示相同的变量
    android定时滚动
    Android GridView中设置了Button以后就不能响应OnItemClick()
    java中转换文件大小
    android 的代码仓库
    Eclipse中代码提示功能补全
    poj 3635 Full Tank? (优先队列 + bfs)
    hdu 4279 Number (规律题 2012 ACM/ICPC Asia Regional Tianjin Online )
  • 原文地址:https://www.cnblogs.com/rausen/p/4508900.html
Copyright © 2011-2022 走看看