• [BZOJ1934][Shoi2007]Vote 善意的投票[最小割]


    建图方式:
    S->同意 ,反对->T

    对于每一对好友连容量为1的边

    #include <bits/stdc++.h>
    using namespace std;
    const int inf = 1e9;
    const int MAXN = 3e2+7;
    const int MAXM = 2e5+7;
    int n, m, s, t, dep[MAXN], maxflow;
    struct Edge {
        int v, w, next;
    } G[MAXM];
    int tot = 1, head[MAXN], cur[MAXN];
    inline void add(int u, int v, int w) {
        G[++tot].v=v, G[tot].w=w, G[tot].next=head[u];
        head[u]=tot;
    }
     
    bool bfs(int s, int t) {
        memset(dep, 0x7f, sizeof dep);
        memcpy(cur+1, head+1, n*4+8);
        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) {
            cur[u] = i;
            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;
    }
     
    void dinic(int s, int t) {
        while(bfs(s, t)) maxflow += dfs(s, t, inf);
    }
     
    int main(void) {
        // memset(head, -1, sizeof head);
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &s);
            if (s) add(n+1, i, 1), add(i, n+1, 0);
            else add(i, n+2, 1), add(n+2, i, 0);
        }
        for(int i = 1; i <= m; ++i) {
            int u, v;
            scanf("%d%d", &u, &v);
            add(u, v, 1), add(v, u, 1);
    //      add(u, v, 0), add(v, u, 0);//加不加都行,因为不会退流
        }
        dinic(n+1, n+2);
        printf("%d", maxflow);
        return 0;
    }
    
  • 相关阅读:
    二进制中1的个数
    原码、反码、补码,计算机中负数的表示
    win10安装MySQL
    X86、X64、X86_64
    windows搭建深度学习环境
    驱动
    cpu、gpu
    常见的文件系统
    UltralSO制作U盘启动盘
    save、load
  • 原文地址:https://www.cnblogs.com/storz/p/10191524.html
Copyright © 2020-2023  润新知