zoukankan      html  css  js  c++  java
  • UVA-3231 Fair Share 二分流量

    题面

    链接:https://vjudge.net/problem/UVALive-3231

    题意

    给定n个机器,m个工作,每个工作可以给两个机器中的某一个做,问每台机器做的工作的最大值最小是多少

    题解

    网络流

    首先源点向每个工作连一条容量为1的边,代表每个工作只能被做一次,然后每个工作向机器连边,容量为1,每个机器向汇点怎么连边呢?为了让每个机器做的工作量最大值最小,我们可以二分答案,机器向汇点连边,容量为二分的值,如果满流,说明每个工作都有人做,可以继续减小,最小值就是答案

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int N = 20050;
    struct node {
        int v, cap, nxt;
        node () {}
        node (int v, int cap, int nxt): v(v), cap(cap), nxt(nxt) {}
    } edge[N * 100];
    int head[N], tot;
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    int dep[N];
    void adde(int u, int v, int w) {
        edge[tot] = node(v, w, head[u]);
        head[u] = tot++;
        edge[tot] = node(u, 0, head[v]);
        head[v] = tot++;
    }
    int cur[N];
    int gap[N];
    int pre[N];
    int sap(int s, int t, int n) {
        memset(dep, 0, sizeof(dep));
        memset(gap, 0, sizeof(gap));
        memcpy(cur, head, sizeof(head));
        memset(pre, 0, sizeof(pre));
        gap[0] = n;
        int u = s;
        pre[u] = -1;
        int ans = 0;
        while (dep[s] < n) {
            if (u == t) {
                int minn = inf;
                for (int i = pre[u]; ~i; i = pre[edge[i ^ 1].v]) {
                    if (minn > edge[i].cap) minn = edge[i].cap;
                }
                for (int i = pre[u]; ~i; i = pre[edge[i ^ 1].v]) {
                    edge[i].cap -= minn;
                    edge[i ^ 1].cap += minn;
                }
                u = s;
                ans += minn;
                continue;
            }
            bool flag = false;
            int v;
            for (int i = cur[u]; ~i; i = edge[i].nxt) {
                v = edge[i].v;
                if (edge[i].cap && dep[v] + 1 == dep[u]) {
                    flag = true;
                    cur[u] = pre[v] = i;
                    break;
                }
            }
            if (flag) {
                u = v;
                continue;
            }
            int minn = n;
            for (int i = head[u]; ~i; i = edge[i].nxt) {
                if (edge[i].cap && dep[edge[i].v] < minn) {
                    minn = dep[edge[i].v];
                    cur[u] = i;
                }
            }
            gap[dep[u]]--;
            if (!gap[dep[u]]) return ans;
            dep[u] = minn + 1;
            gap[dep[u]]++;
            if (u != s) u = edge[pre[u] ^ 1].v;
        }
        return ans;
    }
    int a[N], b[N];
    int main () {
        int cse;
        scanf("%d", &cse);
        while (cse--) {
            init();
            int n, m;
            scanf("%d%d", &n, &m);
            int s = 0, t = n + m + 1;
            for (int i = 1; i <= m; i++) {
                scanf("%d%d", &a[i], &b[i]);
            }
            int l = 0, r = 20000;
            int ans = inf;
            while (l <= r) {
                int mid = (l + r) >> 1;
                init();
                for (int i = 1; i <= m; i++) {
                    adde(i, a[i] + m, 1);
                    adde(i, b[i] + m, 1);
                    adde(s, i, 1);
                }
                for (int i = 1; i <= n; i++) {
                    adde(i + m, t, mid);
                }
    
                int now = sap(s, t, n + m + 2);
                if (now == m) {
                    ans = min(ans, mid);
                    r = mid - 1;
                }
                else l = mid + 1;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark RDD(Resilient Distributed Datasets)论文
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    【机器学习实战】第10章 K-Means(K-均值)聚类算法
    [译]flexbox全揭秘
  • 原文地址:https://www.cnblogs.com/artoriax/p/12203477.html
Copyright © 2011-2022 走看看