zoukankan      html  css  js  c++  java
  • [BZOJ3504][P3163][CQOI2014]危桥[最大流]

    往返一次相当于走两次

    危桥流量为2,正常边流量为inf

    源点连 (a_1,a_2),流量为 (2 cdot a_n)(b_1,b_2)连汇点,流量为(2 cdot b_n)

    一般想来如果最大流(ge 2cdot left(a_n+b_n ight))就输出 Yes

    注意到如果(a)的流量(> 2*an),那么流量可能从(a_1)流到(b_2),所以交换(b_1),(b_2)再做一次最大流

    #include <bits/stdc++.h>
    using namespace std;
     
    bool Debug;
     
    const int mod = 1e9+7;
    const int MAXN = 55, MAXM = 5e5+7, inf = 1e9;
     
    struct Edge{
      int v, w, next;
    }G[MAXM<<1]; int head[MAXN], n, m, s, t, a0, a1, a2, an, bn, b0, b1, b2, b3, a3, tot = 1, cur[MAXN], dep[MAXN];
    char mat[55][53];
    inline void add(int u, int v, int w) {
      G[++tot] = (Edge){v, w, head[u]}; head[u] = tot;
      G[++tot] = (Edge){u, 0, head[v]}; head[v] = tot;
    }
     
    bool bfs(int s, int t) {
        memset(dep, 0x7f, sizeof dep);
        memcpy(cur, head, sizeof cur);
        queue<int>q;
        while(!q.empty()) q.pop();
        dep[s] = 0; q.push(s); 
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(int i = head[u]; i; i = G[i].next) {
                int v = G[i].v, w = G[i].w;
                if (dep[v] > inf && w) {
                    dep[v] = dep[u] + 1;
                    if (v == t) return 1;
                    q.push(v);
                }
            }
        }
        return dep[t] < inf;
    }
     
    int dfs(int u, int t, int limit) {
        if (u == t || !limit) return limit;
        int flow = 0, f;
        for(int &i = cur[u]; i; i = G[i].next) {
            int v = G[i].v, w = G[i].w;
            if (dep[v] == dep[u] + 1 && (f = dfs(v, t, min(w, limit)))) {
                flow += f;
                limit -= f;
                G[i].w -= f;
                G[i^1].w += f;
                if (!limit) break;
            }
        }
        return flow;
    }
    inline int dinic() {
      s = 0, t = n+1; int ret = 0;
      tot = 1, memset(head, 0, sizeof head);
      for(int i = 1; i <= n; ++i) {
        for(int j = 1; j < i; ++j) {
          if (mat[i][j] == 'O') add(i, j, 2), add(j, i, 2);
          else if (mat[i][j] == 'N') add(i, j, inf), add(j, i, inf);
        }
      }
      add(s, a1, 2 * an), add(s, b1, 2 * bn), add(a2, t, 2 * an), add(b2, t, 2 * bn);
      while(bfs(s, t)) ret += dfs(s, t, inf);
      return ret; 
    }
    int main() {
      #ifdef LOCAL_DEBUG
        Debug = 1;
        // freopen("data.in", "r", stdin);
        // freopen("data.out", "w", stdout);
      #endif
      while(~scanf("%d%d%d%d%d%d%d", &n, &a1, &a2, &an, &b1, &b2, &bn)) {
        ++a1, ++a2, ++b1, ++b2;
        for(int i = 1; i <= n; ++i) scanf("%s", mat[i]+1);
        int ans1 = dinic(); swap(b1, b2); int ans2 = dinic();
        // cout << ans1 << ' ' << ans2 << endl;
        an = (an + bn) * 2;
        puts((ans1>=an && ans2 >= an)?"Yes":"No");
      }
      return 0;
    }
    
    
  • 相关阅读:
    大二上每日总结
    大二上每日总结
    大二上每日总结
    大二上每日总结
    大二上每日总结
    大二上每日总结
    MyBatis(八)MyBatis逆向工程
    MyBatis(七)SSM 整合:MyBatisSpringSpringMVC 整合
    MyBatis(九)工作原理 之 框架分层架构
    Interesting Finds: 2008.06.01
  • 原文地址:https://www.cnblogs.com/storz/p/10191253.html
Copyright © 2011-2022 走看看