zoukankan      html  css  js  c++  java
  • Loj 6002 最小路径覆盖(最大流)

    题意:

    求不相交的最小路径覆盖

    思路:

    连边跑二分图,匹配一条边相当于缩了一条边,答案为n-maxflow

    如果是求可以相交的最小路径覆盖的话,先用Floyd跑出可达矩阵,然后所有可达的点连边跑二分图即可

    代码:

    这个dinic板子加边前要tot=1,否则每一对正反向流会乱掉

    由于本题要输出方案,这里有两份代码,一份是跑最大流的时候记录流向,另一份是根据残余网络纪录流向

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <set>
    #include <vector>
    #include <ctime>
    #include <map>
    
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a, b) memset(a, b, sizeof(a))
    #define lson l, mid, root << 1
    #define rson mid + 1, r, root << 1 | 1
    #define lc root << 1
    #define rc root << 1 | 1
    #define lowbit(x) ((x) & (-x))
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PI;
    typedef pair<ll, ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 1e9 + 7;
    const int maxn = 4e4 + 100;
    const int maxm = 4e5 + 100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int head[maxn], d[maxn];                //
    int ver[maxm], edge[maxm], Next[maxm];  // edge[i]: c for edge_i
    int n, m, s, t, tot, maxflow;
    queue<int> q;
    int st[maxn];
    void add(int x, int y, int z) {
        ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;
        st[tot]=x;
        ver[++tot] = x, edge[tot] = 0, Next[tot] = head[y], head[y] = tot;
        st[tot]=y;
    }
    int du[maxn];
    bool bfs() {
        mem(d, 0);
        while (!q.empty()) q.pop();
        q.push(s);
        d[s] = 1;
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int i = head[x]; i; i = Next[i]) {
                if (edge[i] && !d[ver[i]]) {
                    q.push(ver[i]);
                    d[ver[i]] = d[x] + 1;
                    if (ver[i] == t)
                        return true;
                }
            }
        }
        return false;
    }
    int nx[maxn];
    int dinic(int x, int flow) {
        if (x == t)
            return flow;
        int rest = flow, k;
        for (int i = head[x]; i; i = Next[i]) {
            if (edge[i] && d[ver[i]] == d[x] + 1) {
                k = dinic(ver[i], min(rest, edge[i]));
                if (!k) {
                    d[ver[i]] = 0;
                } else {
                    edge[i] -= k;
                    edge[i ^ 1] += k;
                    rest -= k;
                }
            }
        }
        return flow - rest;
    }
    int vis[maxn];
    int pre[maxn];
    int main() {
        mem(pre, -1);
        mem(nx,-1);
        s = 0;
        t = 1;
        tot = 1;
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= m; i++) {
            int x, y;
            scanf("%d %d", &x, &y);
            x *= 2;
            y *= 2;
            add(x, y + 1, 1);
        }
        for (int i = 1; i <= n; i++) {
            add(s, i * 2, 1);
            add(i * 2 + 1, t, 1);
        }
        int maxflow = 0;
        int flow;
        while (bfs()) {
            while (1) {
                flow = dinic(s, inf);
                if (flow == 0)
                    break;
                maxflow += flow;
            }
        }
        for(int i = 2; i <= tot; i++){
            if(edge[i]==0&&st[i]%2==0&&st[i]>=2&&st[i]<=2*n&&ver[i]!=s){
                int x = st[i]/2;
                int y = (ver[i]-1)/2;
                //printf("%d %d
    ",x,y);
                pre[y] = x;
                nx[x] = y;
            }
        }
        for(int i = 1; i <= n; i++){
            if(pre[i]==-1){
                int x = i;
                while(x!=-1){
                    printf("%d ", x);
                    x= nx[x];
                }
                printf("
    ");
            }
        }
        printf("%d
    ", n - maxflow);
        return 0;
    }
    
    /*
    5 3
    1 2 3 4 5
    1 2 3
    2 1 4
    4 3 5
     */
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <set>
    #include <vector>
    #include <ctime>
    #include <map>
    
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a, b) memset(a, b, sizeof(a))
    #define lson l, mid, root << 1
    #define rson mid + 1, r, root << 1 | 1
    #define lc root << 1
    #define rc root << 1 | 1
    #define lowbit(x) ((x) & (-x))
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PI;
    typedef pair<ll, ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 1e9 + 7;
    const int maxn = 4e2 + 100;
    const int maxm = 4e5 + 100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int head[maxn], d[maxn];                //
    int ver[maxm], edge[maxm], Next[maxm];  // edge[i]: c for edge_i
    int n, m, s, t, tot, maxflow;
    queue<int> q;
    void add(int x, int y, int z) {
        ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;
    
        ver[++tot] = x, edge[tot] = 0, Next[tot] = head[y], head[y] = tot;
    }
    int du[maxn];
    bool bfs() {
        mem(d, 0);
        while (!q.empty()) q.pop();
        q.push(s);
        d[s] = 1;
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int i = head[x]; i; i = Next[i]) {
                if (edge[i] && !d[ver[i]]) {
                    q.push(ver[i]);
                    d[ver[i]] = d[x] + 1;
                    if (ver[i] == t)
                        return true;
                }
            }
        }
        return false;
    }
    int nx[maxn];
    int dinic(int x, int flow) {
        if (x == t)
            return flow;
        int rest = flow, k;
        for (int i = head[x]; i; i = Next[i]) {
            if (edge[i] && d[ver[i]] == d[x] + 1) {
                k = dinic(ver[i], min(rest, edge[i]));
                if (!k) {
                    d[ver[i]] = 0;
                } else {
                    nx[x] = ver[i];
                    edge[i] -= k;
                    edge[i ^ 1] += k;
                    rest -= k;
                }
            }
        }
        return flow - rest;
    }
    int vis[maxn];
    int pre[maxn];
    int main() {
        mem(pre, -1);
        s = 404;
        t = 402;
        tot = 1;
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= m; i++) {
            int x, y;
            scanf("%d %d", &x, &y);
            x *= 2;
            y *= 2;
            add(x, y + 1, 1);
        }
        for (int i = 1; i <= n; i++) {
            add(s, i * 2, 1);
            add(i * 2 + 1, t, 1);
        }
        int maxflow = 0;
        int flow;
        while (bfs()) {
            while (1) {
                flow = dinic(s, inf);
                if (flow == 0)
                    break;
                maxflow += flow;
            }
        }
        for (int i = 1; i <= n; i++) {
            pre[(nx[i * 2] - 1) / 2] = i;
        }
    
        for (int i = 1; i <= n; i++) {
            if (vis[i])
                continue;
            if (pre[i] == -1) {
                int x = i;
                while (x) {
                    vis[x] = 1;
                    printf("%d ", x);
                    x = (nx[x * 2] - 1) / 2;
                }
                printf("
    ");
            }
        }
        printf("%d
    ", n - maxflow);
        return 0;
    }
    
    /*
    5 3
    1 2 3 4 5
    1 2 3
    2 1 4
    4 3 5
     */
  • 相关阅读:
    常用快捷键知识汇总
    按照给定区间产生指定数目的随机数—C#
    OC (3) 类 与 类方法 (便利构造器) iOS
    OC (2) 基础知识分析对象,创建类,自定义初始化方法 iOS
    OC (1) 类和对象:ObjectiveC概述、面向对象编程、类和对象、实例变量操作 iOS
    OC (6) Block、数组高级:Block语法、Block使用、Block实现数组排序 iOS
    OC (7) 类的扩展 iOS
    OC (5) 字典、集、数组排序:字典类、集合类、数组数组排序、字典、集合的快速遍历、数组排序 iOS
    OC (4)NSString、NSArray、NSNumber、使用苹果帮助文档、值对象 iOS
    jquery 里 $(this)的用法
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10671158.html
Copyright © 2011-2022 走看看