zoukankan      html  css  js  c++  java
  • 【洛谷 P2756】 飞行员配对方案问题(二分图匹配,最大流)

    题目链接
    这不是裸的二分图匹配吗?
    而且匈牙利算法自带记录方案。。
    但既然是网络流24题,那就用网络流来做吧。
    具体就是从源点向左边每个点连一条流量为1的边,两边正常连边,流量都是一,右边所有点向汇点连一条流量为1的边,然后跑(Dinic)就行了。
    怎么记录方案?枚举左边所有点连的所有边,如果剩余流量为0就是和这条边那边的点匹配了咯。
    在家直接用在线IDE写的,一遍过了。

    #include <cstdio>
    #include <queue>
    using namespace std; 
    #define INF 2147483647
    inline int read(){
        int s = 0, w = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
        while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0',ch = getchar();
        return s * w;
    }
    const int MAXN = 1000010;
    struct Edge{
        int next, from, to, rest;
    }e[MAXN];
    int head[MAXN], num = 1;
    inline void Add(int from, int to, int flow){
        //printf("%d %d
    ", from, to);
        e[++num] = (Edge){ head[from], from, to, flow }; head[from] = num;
        e[++num] = (Edge){ head[to], to, from, 0 }; head[to] = num;
    }
    int flow[MAXN], pre[MAXN], dfn[MAXN];
    int h[MAXN], p[MAXN], f[100][100];
    int n, m, s, t, a, b, now, Time, ans;
    queue <int> q;
    int RoadExist(){
        while(q.size()) q.pop();
        flow[s] = INF; pre[t] = 0; q.push(s); dfn[s] = ++Time;
        while(q.size()){
          now = q.front(); q.pop();
          for(int i = head[now]; i; i = e[i].next)
             if(e[i].rest && dfn[e[i].to] != Time)
               dfn[e[i].to] = Time, flow[e[i].to] = min(flow[now], e[i].rest), q.push(e[i].to), pre[e[i].to] = i;
        }
        return pre[t];
    }
    int dinic(){
        int ans = 0;
        while(RoadExist()){
          ans += flow[t];
          now = t;
          while(now != s){
            e[pre[now]].rest -= flow[t];
            e[pre[now] ^ 1].rest += flow[t];
            now = e[pre[now]].from;
          }
        }
        return ans; 
    }
    int main(){
        s = 99999; t = 100000;
        n = read(); m = read();
        while(233){
            a = read(); b = read();
            if(a == -1) break;
            Add(a, b, 1);
        }
        for(int i = 1; i <= n; ++i)
           Add(s, i, 1);
        for(int i = n + 1; i <= m; ++i)
           Add(i, t, 1);
        ans = dinic();
        printf("%d
    ", ans);
        for(int i = 1; i <= n; ++i)
           for(int j = head[i]; j; j = e[j].next)
              if(!e[j].rest && e[j].to != s)
                printf("%d %d
    ", i, e[j].to);
        return 0;
    }
    
  • 相关阅读:
    mvc的视图渲染方式
    Numpy系列(六)- 形状操作
    Numpy系列(五)- 复制和视图
    Numpy系列(四)- 索引和切片
    Numpy系列(三)- 基本运算操作
    Numpy系列(二)- 数据类型
    Numpy系列(一)- array
    HTML参考手册
    pkuseg:一个多领域中文分词工具包
    Nginx实现JWT验证-基于OpenResty实现
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/10133144.html
Copyright © 2011-2022 走看看