zoukankan      html  css  js  c++  java
  • [题解] PowerOJ 1742 试题库问题 (最大流)

    - 传送门 -

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

    #  1742: 试题库问题 SPJ

    Time Limit: 10000 MS Memory Limit: 65536 KB
    Total Submit: 294 Accepted: 140 Page View: 843

    Description

    假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别 属性。现要从题库中抽取m 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个 满足要求的组卷算法。 编程任务: 对于给定的组卷要求,计算满足要求的组卷方案。

    Input

    由文件input.txt提供输入数据。文件第1行有2个正整数k和n (2 <=k<= 20, k<=n<= 1000) k 表示题库中试题类型总数,n 表示题库中试题总数。第2 行有k 个正整数,第i 个正整数 表示要选出的类型i 的题数。这k个数相加就是要选出的总题数m。接下来的n行给出了题 库中每个试题的类型信息。每行的第1 个正整数p表明该题可以属于p类,接着的p个数是 该题所属的类型号。

    Output

    程序运行结束时,将组卷方案输出到文件output.txt 中。文件第i 行输出 “i:”后接类 型i的题号。如果有多个满足要求的方案,只要输出1 个方案。如果问题无解,则输出“No Solution!”。

    3 15
    3 3 4 2
    1 2
    1 3
    1 3
    1 3
    1 3
    3 1 2 3
    2 2 3
    2 1 3
    1 2
    1 2
    2 1 2
    2 1 3
    2 1 2
    1 1
    3 1 2 3

    1: 1 6 8
    2: 7 9 10
    3: 2 3 4 5

    Source

    线性规划与网络流24题

     

    - 思路 -

     起点 -> 试题类型 (试题数量)
     试题类型 -> 试题 (1)
     试题 -> 终点 (1)
     简单的建模...
     求最大流...
     
     细节见代码.
     

    - 代码 -

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
     
    const int N = 1100;
    const int M = 1e5;
    const int inf = 0x3f3f3f3f;
    queue<int> q;
     
    int NXT[M], V[M], TO[M], FRM[M];
    int HD[N], CUR[N], DIS[N];
    int n, m, ss, tt, sz, cnt, tot, ans;
     
    bool bfs() {
        memset(DIS, -1, sizeof (DIS));
        DIS[ss] = 0;
        q.push(ss);
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int i = HD[u]; i != -1; i = NXT[i]) {
                if (V[i] && DIS[TO[i]] < 0) {
                    DIS[TO[i]] = DIS[u] + 1;
                    q.push(TO[i]);
                }
            }
        }
        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) {
            printf("%d:", i);
            for (int j = HD[i]; j != -1; j = NXT[j]) {
                if (V[j] == 0 && TO[j] != ss) printf(" %d", TO[j] - n);
                //开始没注意细节wa了一发
            }
            printf("
    ");
        }
    }
     
    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++;
    }
     
    int main () {
        memset(HD, -1, sizeof (HD));
        scanf("%d%d", &n, &m);
        ss = 0, tt = n + m + 1;
        for (int i = 1, x; i <= n; ++i) {
            scanf("%d", &x);
            add(ss, i, x);
            tot += x;
        }
        for (int i = 1, x, a; i <= m; ++i) {
            scanf("%d", &x);
            while (x--) {
                scanf("%d", &a);
                add(a, i + n, 1);
            }
            add(i + n, tt, 1);
        }
        if (tot != dinic())
            printf("No Solution!
    ");
        else
            print();
        return 0;
    }
    
  • 相关阅读:
    metasploit 教程之基本参数和扫描
    sql注入学习 sqlliab教程 lesson1 (sqlliab搭建教程)
    metasploit 教程之信息收集
    渗透.
    sqlmap基础入门超详细教程
    网络调试助手 全平台
    python3中的socket
    python3 udp版简单的聊天器
    提交表单外的数据方法
    centos7下端口映射
  • 原文地址:https://www.cnblogs.com/Anding-16/p/7418824.html
Copyright © 2011-2022 走看看