zoukankan      html  css  js  c++  java
  • 洛谷P2764 最小路径覆盖问题(二分图)

    题意

    给出一张有向无环图,求出用最少的路径覆盖整张图,要求路径在定点处不相交

    输出方案

    Sol

    定理:路径覆盖 = 定点数 - 二分图最大匹配数

    直接上匈牙利

    输出方案的话就不断的从一个点跳匹配边

    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int MAXN = 1e5 + 10, INF = 1e9 + 10;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        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;
    vector<int> v[MAXN];
    int link[MAXN], vis[MAXN], cnt = 1;
    bool Arg(int x) {
        for(int i = 0; i < v[x].size(); i++) {
            int to = v[x][i];
            if(vis[to] == cnt) continue; vis[to] = cnt;
            if(!link[to] || Arg(link[to]))
                {link[to] = x; link[x] = to; return 1;}
        }
        return 0;
    }
    int Hunary() {
        int ans = 0;
        for(int i = 1; i <= N; i++, cnt++)
            if(Arg(i))
                ans++;
        return ans;
    }
    int main() {
        N = read(); M = read();
        for(int i = 1; i <= M; i++) {
            int x = read(), y = read();
            v[x].push_back(y + N);
        }
        int ans = N - Hunary();
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= N; i++) {
            int x = i + N;
            if(vis[i]) continue;
            do 
                printf("%d ", x = x - N);
            while(vis[x] = 1, x = link[x]);
            puts("");
        }
        printf("%d", ans);
        return 0;
    }
  • 相关阅读:
    类的加载过程
    算法模板之基数排序
    算法模板之Dijkstra
    算法模板之SPFA
    算法模板之树状数组
    算法模板之排序
    深入JVM-自动内存管理(读书笔记)
    VMware Fault-Tolerant Virtual Machine 论文总结
    深入JVM--高效并发(读书笔记)
    欧拉素数筛
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9366455.html
Copyright © 2011-2022 走看看