• Luogu P4014 「 网络流 24 题 」分配问题


    解题思路

    还是建立超级源点和超级汇点,又因为题目给出规定一个人只能修一个工件,所以建图的时候还要讲容量都设为$1$。

    人的编号是$1 ightarrow n$,工件的编号是$n+1 ightarrow 2 imes n$。人和超级源点连边,工件和超级汇点连边,跑一个最小费用最大流和最大费用最大流。

    附上代码

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    const int maxnode = 208, maxedge = 40010, INF = 2147483647;
    inline int read() {
        int x = 0, f = 1; char c = getchar();
        while (c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') {x = x*10 + c-'0'; c = getchar();}
        return x * f;
    }
    int n, m, dis[maxnode], Depth[maxnode], head[maxnode], cnt = 1, s, t, Ans;
    struct edge {
        int nxt, u, v, w;
    }ed[maxedge];
    inline void addedge(int x, int y, int cap) {
        ed[++cnt].nxt = head[x];
        ed[cnt].v = y, ed[cnt].w = cap, ed[cnt].u = x;
        head[x] = cnt;
    }
    inline bool BFS() {
        queue<int> Q;
        memset(Depth, 0, sizeof(Depth));
        Depth[s] = 1, Q.push(s);
        int u;
        while(!Q.empty()) {
            u = Q.front();
            Q.pop();
            for(int i=head[u]; i; i=ed[i].nxt) {
                if(ed[i].w > 0 && Depth[ed[i].v] == 0) {
                    Depth[ed[i].v] = Depth[u] + 1;
                    Q.push(ed[i].v);
                    if(ed[i].v == t) return true;
                }
            }
        }
        return false;
    }
    inline int Dinic(int u, int cap) {
        if(u == t) return cap;
        int delta;
        for(int i=head[u]; i; i=ed[i].nxt) {
            if(Depth[ed[i].v] == Depth[u] + 1 && ed[i].w > 0) {
                delta = Dinic(ed[i].v, min(cap, ed[i].w));
                if(delta > 0) {
                    ed[i].w -= delta;
                    ed[i^1].w += delta;
                    return delta;
                }
            }
        }
        return 0;
    }
    int main() {
        n = read(), m = read();
        s = 0, t = n+m+1;
        for(int i=1; i<=n; i++) addedge(s, i, 1), addedge(i, s, 0);
        for(int i=n+1; i<=m; i++) addedge(i, t, 1), addedge(t, i, 0);
        static int x, y;
        while (1) {
            x = read(), y = read();
            addedge(x, y, 1), addedge(y, x, 0);
            if(x == -1 && y == -1) break;
        }
        while (BFS()) Ans += Dinic(s, INF);
        if(Ans) printf("%d
    ", Ans);
        else printf("No Solution!
    ");
        if(Ans) {
            for(int i=2; i<=cnt; i+=2) {
                if(ed[i].v != s && ed[i].v != t && ed[i^1].v != s && ed[i^1].v != t)
                    if(ed[i^1].w != 0)printf("%d %d
    ", ed[i].u, ed[i].v);
            }
        }
        return 0;
    }
  • 相关阅读:
    【老孙随笔】项目经理要如何看待技术?
    从菜鸟到CTO——你的目标需要管理
    FormatX源代码格式化插件V2.0版
    JavaScript面向对象之静态与非静态类
    FormatX源代码格式化插件
    正确捕获 WCF服务调用中发生的异常及处理技巧
    2010,应该感谢的那些人以及那些未完成的事
    使用IErrorHandle对WCF服务器进行异常处理
    代码重构之路的艰辛
    从读取Excel文件引申出的问题(上)
  • 原文地址:https://www.cnblogs.com/bljfy/p/9546017.html
Copyright © 2020-2023  润新知