• [题解] PowerOJ 1738 最小路径覆盖问题 (最大流)


    - 传送门 -

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

    #1738: 最小路径覆盖问题 SPJ

    Time Limit: 1000 MS Memory Limit: 65536 KB
    Total Submit: 198 Accepted: 84 Page View: 697

    Description

    给定有向图G=(V,E)。设P 是G 的一个简单路(顶点不相交)的集合。如果V 中每个 顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖。P 中路径可以从V 的任何一个顶 点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少 的路径覆盖。 设计一个有效算法求一个有向无环图G 的最小路径覆盖。 提示:设V={1,2,... ,n},构造网络G1=(V1,E1)如下: 每条边的容量均为1。求网络G1的( x0 , y0 )最大流。 编程任务: 对于给定的有向无环图G,编程找出G的一个最小路径覆盖。

    Input

    由文件input.txt提供输入数据。文件第1 行有2个正整数n和m。n是给定有向无环图 G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。

    Output

    程序运行结束时,将最小路径覆盖输出到文件output.txt 中。从第1 行开始,每行输出 一条路径。文件的最后一行是最少路径数。

    11 12
    1 2
    1 3
    1 4
    2 5
    3 6
    4 7
    5 8
    6 9
    7 10
    8 11
    9 11
    10 11

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

    Source

    线性规划与网络流24题

     

    - 思路 -

     将一个点视为两个, 一个作为起点, 已给作为终点, n 个起点放在集合 X 中, n 个终点放在集合 Y 中, 从而把有向边转为集合 X 中的点到集合 Y 的点的有向边, 这样就得到了二分图匹配的模型.
     二分图匹配的模型转费用流上篇已经讲了就不再赘述.
     二分图中有一条匹配边则说明有一个点计入一条边中, 所以ans = 点数 - 匹配边数.
     
     细节见代码.
     

    - 代码 -

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
     
    const int N = 400;
    const int M = 2e4 + 5;
    const int inf = 0x3f3f3f3f;
     
    int NXT[M], FRM[M], TO[M];
    int V[M], CUR[N], HD[N];
    int DIS[N], GO[N];
    int n, m, ss, tt, sz, cnt;
    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));
        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]) {
                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 = 0; i < cnt; i += 2) {
            if (V[i] == 0) GO[FRM[i]] = TO[i] - n;
        }
        memset(DIS, 0, sizeof (DIS));
        int i = 1, j;
        while (i <= n) {
            if (DIS[i]) {
                i++;
                continue;
            }
            printf("%d", i);
            DIS[i] = 1;
            j = i;
            while (GO[j]) {
                j = GO[j];
                DIS[j] = 1;
                printf(" %d", j);
            }
            printf("
    ");
        }
    }
     
    int main() {
        scanf("%d%d", &n, &m);
        ss = n * 2 + 1, tt = n * 2 + 2;
        memset(HD, -1, sizeof (HD));
        for (int i = 1, x, y; i <= m; ++i) {
            scanf("%d%d", &x, &y);
            add(x, y + n, 1);
            cnt = sz;
        }
        for (int i = 1; i <= n; ++i) {
            add(ss, i, 1);
            add(i + n, tt, 1);
        }
        int tmp = dinic();
        print();
        printf("%d", n - tmp);
        return 0;
    }
    
  • 相关阅读:
    mysql GRANT ALL PRIVILEGES 限制某个或所有客户端都可以连接至mysql
    MySql开启远程用户登录GRANTALLPRIVILEGESON*.*TO'root'@'%'I MySql开启远程用户登录GRANTALLPRIVILEGESON*.*TO'root'@'%'I
    php中 -> 和 => 和 :: 的用法 以及 self 和 $this 的用法
    mysql case when then else end 的用法
    C/C++ 程序的build过程
    Git 笔记
    English Snippets
    Ubuntu 使用笔记
    在CentOS上安装Sublime Text
    hihoCoder #1379 Emulator
  • 原文地址:https://www.cnblogs.com/Anding-16/p/7410725.html
Copyright © 2020-2023  润新知