• P2756 飞行员配对方案问题


    原题链接

    • 题解:建图就类似二分图找最大匹配,然后如果输出方案的话,那就是残留网络中流量为0的正向边就是使用的,所以直接找即可。
    • 代码:
    #include <iostream>
    #include <queue>
    #include <map>
    #include <cstring>
    using namespace std;
    #define int long long
    map<int,int>mp;
    const int N = 2200, M = 220000;
    const int inf = 99999999999;
    int n, nn, S, T;
    int h[M], ne[M], to[M], f[M], idx;
    void add(int u, int v, int w) {
        ne[idx] = h[u], to[idx] = v, f[idx] = w, h[u] = idx ++;
        ne[idx] = h[v], to[idx] = u, f[idx] = 0, h[v] = idx ++;
    }
    int d[N],cur[N];
    queue<int>q;
    bool bfs() {
        while (!q.empty())q.pop();
        q.push(S);
        memset(d, -1, sizeof d);
        d[S] = 0;
        cur[S] = h[S];
        while (!q.empty()) {
            auto u = q.front();
            q.pop();
            for (int i = h[u]; ~i; i = ne[i]) {
                int v= to[i];
                if (d[v] == -1 && f[i]) {
                    d[v] = d[u] + 1;
                    cur[v] = h[v];
                    if (v == T)return 1;
                    q.push(v);
                }
            }
        }
        return 0;
    }
    int ans[N];
    int ans_cnt = 0;
    int dfs(int u, int limit) {
        if (u == T)return limit;
        int flow = 0;
        for (int i = cur[u]; ~i && flow < limit; i = ne[i]) {
            int v = to[i];
            cur[u] = i;
            if (f[i] && d[v] == d[u] + 1) {
                int t = dfs(v, min(f[i], limit - flow));
                if (!t)d[v] = -1;
                f[i] -= t;
                f[i^1] += t;
                flow += t;
            }
        }
        if (u > n && u <= nn && flow ==1) {
            ans[++ans_cnt] = u;
        } else if (u >0 && u <= n && flow == 1) {
            ans[++ans_cnt] = u;
        }
        return flow;
    }
    int dinic() {
        int ret = 0, flow;
        while (bfs()) {while (flow = dfs(S, inf))ret += flow;}
    
        return ret;
    }
    signed main() {
        memset(h, -1, sizeof h);
        scanf("%lld%lld%", &n, &nn);
        int u, v;
        S = 0, T = nn + 1;
        while (scanf("%lld%lld", &u, &v)) {
            if (u == -1 && v == -1)break;
            add(u, v , 1);
        }
        for (int i = 1; i <= n; i ++) {
            add(S, i, 1);
        }
        for (int j = n + 1; j <= nn; j ++) {
            add(j, T, 1);
        }
        printf("%lld
    ", dinic());
        for (int i = 0; i < idx; i += 2) {
            if (to[i ^ 1] <= n && to[i]> n && !f[i]) {
                printf("%d %d
    ", to[i ^ 1], to[i]);
            }
        }
    }
    
  • 相关阅读:
    oracle impdp 导入
    oracle权限的分配
    Oracle CASE WHEN 用法介绍
    Oracle自动执行任务(存储过程)
    PL/SQL注册码
    ORACLE基本的sql语句
    ORACLE导出导入问题和表空间问题
    PLSQL笔记
    JSEL 表达式
    asp.net HTTP教程一(HTTP运行期与页面执行模型 )
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14651640.html
Copyright © 2020-2023  润新知