zoukankan      html  css  js  c++  java
  • [题解] PowerOJ 1740 圆桌问题 (最大流)

    - 传送门 -

     https://www.oj.swust.edu.cn/problem/show/1740

    #  1740: 圆桌问题 SPJ Time Limit: 1000 MS Memory Limit: 65536 KB Total Submit: [423](https://www.oj.swust.edu.cn/status?pid=1740) Accepted: [187](https://www.oj.swust.edu.cn/status?pid=1740&result=0) Page View: 1137

    Description

    假设有来自n 个不同单位的代表参加一次国际会议。每个单位的代表数分别为 ri,i=1,2,...,n 。会议餐厅共有m张餐桌,每张餐桌可容纳ci(i=1,2, ,m) 个代表就餐。 为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐。试设计一个算法, 给出满足要求的代表就餐方案。 编程任务: 对于给定的代表数和餐桌数以及餐桌容量,编程计算满足要求的代表就餐方案。

    Input

    由文件input.txt提供输入数据。文件第1行有2 个正整数m和n,m表示单位数,n表 示餐桌数,1<=m<=150, 1<=n<=270。文件第2 行有m个正整数,分别表示每个单位的代表 数。文件第3 行有n个正整数,分别表示每个餐桌的容量。

    Output

    程序运行结束时,将代表就餐方案输出到文件output.txt 中。如果问题有解,在文件第 1 行输出1,否则输出0。接下来的m行给出每个单位代表的就餐桌号。如果有多个满足要 求的方案,只要输出1 个方案。

    4 5
    4 5 3 5
    3 5 2 6 4

    1
    1 2 4 5
    1 2 3 4 5
    2 4 5
    1 2 3 4 5

    Source

    线性规划与网络流24题

     

    - 思路 -

     终于打到容量不为 1 的网络流了!!!
     开始转二分图多重匹配!!!
     和前几题也差不多, 只是起点连向 x 集合(单位)的有向边的容量改为该单位代表数, y 集合(餐桌)连向终点的有向边的容量改为餐桌可容纳代表数, 两集合间的边容量还是都是 1 ,然后求最大流.
     
     细节见代码.
     

    - 代码 -

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
     
    const int N = 500;
    const int M = 1e5 + 5;
    const int inf = 0x3f3f3f3f;
     
    int R[N], C[N];
    int CUR[N];
    int TO[M], NXT[M], V[M];
    int FRM[M], DIS[M], HD[N];
    int tot, n, m, sz, cnt, ss, tt;
    queue<int> q;
     
    void add(int x, int y, int z) {
        FRM[sz] = x; TO[sz] = y; V[sz] = z;
        NXT[sz] = HD[x]; HD[x] = sz++;
        FRM[sz] = y; TO[sz] = x; V[sz] = 0;
        NXT[sz] = HD[y]; HD[y] = sz++;
    }
     
    bool bfs() {
        memset(DIS, -1, sizeof (DIS));
        q.push(ss);
        DIS[ss] = 0;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int i = HD[u]; i != -1; i = NXT[i]) {
                int v = TO[i];
                if (DIS[v] < 0 && V[i]) {
                    DIS[v] = DIS[u] + 1;
                    q.push(v);
                }
            }
        }
        return DIS[tt] > 0;
    }
     
    int dfs(int x, int a) {
        if (x == tt) return a;
        int flow = 0, f;
        for (int& i = CUR[x]; i != -1; i = NXT[i]) {
            if (V[i] && DIS[TO[i]] == DIS[x] + 1)
                if (f = dfs(TO[i], min(a, V[i]))) {
                    V[i] -= f;
                    V[i^1] += f;
                    flow += f;
                    a -= f;
                    if (a == 0) break;
                }
        }
        return flow;
    }
     
    int dinic() {
        int flow = 0;
        while (bfs()) {
            memcpy(CUR, HD, sizeof (HD));
            flow += dfs(ss, inf);
        }
        return flow;
    }
     
    void print() {
        for (int i = 1; i <= n; ++i) {
            for (int j = HD[i]; j != -1; j = NXT[j]) {
                if (!V[j]) printf("%d ", TO[j] - n);
            }
            printf("
    ");
        }
    }
     
    int main() {
        memset(HD, -1, sizeof (HD));
        scanf("%d%d", &n, &m);
        ss = 0, tt = n + m + 1;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &C[i]);
            add(ss, i, C[i]);
            tot += C[i];
        }
        for (int i = 1; i <= m; ++i) {
            scanf("%d", &R[i]);
            add(n + i, tt, R[i]);
        }
        cnt = sz;
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j)
                add(i, n + j, 1);
        if (dinic() == tot) {
            printf("1
    ");
            print();
        }
        else printf("0
    ");
        return 0;
    }
    
  • 相关阅读:
    Net 下安装、调试的常见问题与错误
    解决在网页框架中,页面的样式表失效的方法
    C#.NET Show Text Info
    C#.NET 部署应用程序之ClickOnce
    VS2005 数据库间转移数据(SSIS)
    C#.NET ClickOnce
    SQL2005 还原备份数据
    C#.NET TreeView.cs
    C#.NET SetComboBox Class
    C#.NET GetLocalMachineInfo.cs
  • 原文地址:https://www.cnblogs.com/Anding-16/p/7412452.html
Copyright © 2011-2022 走看看