zoukankan      html  css  js  c++  java
  • 飞行员配对方案问题 【网络流24题】

    输入输出样例

    输入 #1
    5 10
    1 7
    1 8
    2 6
    2 9
    2 10
    3 7
    3 8
    4 7
    4 8
    5 10
    -1 -1
    
    输出 #1
    4
    1 7
    2 9
    3 8
    5 10

    思路

      题目给出两个不同阵营

      不同阵营之间的人可以组队

      一个人只能和一个人组队

      求最大匹配数

      显然可以直接偷懒上匈牙利

      但既然叫网络流24题就用网络流做吧

      建立一个S、一个T表示超级源、汇

      把A阵营的人连S

      B阵营的人连T

      认识的人之间就可以连边

      因为每个人都只能和一个另外阵营的人组队

      说明每个点都只能最多用一次

      所以这些边的 capacity 都是 1

      图建完后,如何输出他们匹配的方案呢

      考虑最小路径那样记录

      但是由于悔边的原因并不好记录

      所以直接从悔边下手

      当一对组合成立

      说明正向边容量 - 1

      则悔边容量应该 + 1

      所以只要是悔边容量变大了的

      那么连着这条边的两个人都是被选中的

      

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 const int inf = 0x3f3f3f3f;
     10 
     11 template<class T>inline void read(T &res)
     12 {
     13     char c;T flag=1;
     14     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     15     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     16 }
     17 
     18 namespace _buff {
     19     const size_t BUFF = 1 << 19;
     20     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     21     char getc() {
     22         if (ib == ie) {
     23             ib = ibuf;
     24             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     25         }
     26         return ib == ie ? -1 : *ib++;
     27     }
     28 }
     29 
     30 int qread() {
     31     using namespace _buff;
     32     int ret = 0;
     33     bool pos = true;
     34     char c = getc();
     35     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     36         assert(~c);
     37     }
     38     if (c == '-') {
     39         pos = false;
     40         c = getc();
     41     }
     42     for (; c >= '0' && c <= '9'; c = getc()) {
     43         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     44     }
     45     return pos ? ret : -ret;
     46 }
     47 
     48 const int maxn = 200007;
     49 
     50 int n, m;
     51 int s, t;
     52 
     53 struct edge{
     54     int from,to;
     55     LL cap,flow;
     56 };
     57 
     58 map<int, int> vis;
     59 
     60 struct DINIC {
     61     int head[maxn << 1], nxt[maxn << 1], edge[maxn << 1], cnt;
     62     int cap[maxn << 1], depth[maxn << 1];
     63 
     64     void init() {
     65         cnt = 1;
     66         memset(head, 0, sizeof(head));
     67     }
     68 
     69     void BuildGraph(int u, int v, int w) {
     70         ++cnt;
     71         edge[cnt] = v;
     72         nxt[cnt] = head[u];
     73         cap[cnt] = w;
     74         head[u] = cnt;
     75 
     76         ++cnt;
     77         edge[cnt] = u;
     78         nxt[cnt] = head[v];
     79         cap[cnt] = 0;
     80         head[v] = cnt;
     81     }
     82 
     83     queue<int> q;
     84 
     85     bool bfs() {
     86         memset(depth, 0, sizeof(depth));
     87         depth[s] = 1;
     88         q.push(s);
     89         while(!q.empty()) {
     90             int u = q.front();
     91             q.pop();
     92             for ( int i = head[u]; i; i = nxt[i] ) {
     93                 int v = edge[i];
     94                 if(depth[v]) {
     95                     continue;
     96                 }
     97                 if(cap[i]) {
     98                     depth[v] = depth[u] + 1;
     99                     q.push(v);
    100                 }
    101             }
    102         }
    103         return depth[t];
    104     }
    105 
    106     int dfs(int u, int dist) {
    107         if(u == t) {
    108             return dist;
    109         }
    110         int flow = 0;
    111         for ( int i = head[u]; i && dist; i = nxt[i] ) {
    112             if(cap[i] == 0)
    113                 continue;
    114             int v = edge[i];
    115             if(depth[v] != depth[u] + 1) {
    116                 continue;
    117             }
    118             int res = dfs(v, min(cap[i], dist));
    119             cap[i] -= res;
    120             cap[i ^ 1] += res;
    121             //printf("cap[%d]:%d
    ",t, cap[t]);
    122             vis[u] = v;
    123             dist -= res;
    124             flow += res;
    125         }
    126         return flow;
    127     }
    128 
    129     int maxflow() {
    130         int ans = 0;
    131         while(bfs()) {
    132             ans += dfs(s, inf);
    133         }
    134         return ans;
    135     }
    136 } dinic;
    137 
    138 int main()
    139 {
    140     //freopen("data.txt", "r", stdin);
    141     read(m); read(n); 
    142     int u, v;
    143     s = 0, t = n + m + 1;
    144     dinic.init();
    145     while(1) {
    146         read(u); read(v);
    147         if(u == -1 && v == -1) {
    148             break;
    149         }
    150         dinic.BuildGraph(u, v, 1);
    151     }
    152     for ( int i = 1; i <= m; ++i ) {
    153         dinic.BuildGraph(s, i, 1);
    154     }
    155     for ( int i = m + 1; i <= m + n; ++i ) {
    156         dinic.BuildGraph(i, t, 1);
    157     }
    158     cout << dinic.maxflow() << endl;
    159     int tot = dinic.cnt;
    160     for ( int i = 2; i <= tot; i += 2 ) {
    161         int u = dinic.edge[i];
    162         int v = dinic.edge[i ^ 1];
    163         if(u == s || u == t || v == s || v == t) {
    164             continue;
    165         }
    166         else {
    167             int cap = dinic.cap[i ^ 1];
    168             if(cap != 0) {
    169                 printf("%d %d
    ",v, u);
    170             }
    171         }
    172     }
    173     return 0;
    174 }
    View Code
    #include <bits/stdc++.h>
    #define dbg(x) cout << #x << "=" << x << endl
    #define eps 1e-8
    #define pi acos(-1.0)

    using namespace std;
    typedef long long LL;

    const int inf = 0x3f3f3f3f;

    template<class T>inline void read(&res)
    {
        char c;T flag=1;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
        while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }

    namespace _buff {
        const size_t BUFF = 1 << 19;
        char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
        char getc() {
            if (ib == ie) {
                ib = ibuf;
                ie = ibuf + fread(ibuf, 1, BUFF, stdin);
            }
            return ib == ie ? -1 : *ib++;
        }
    }

    int qread() {
        using namespace _buff;
        int ret = 0;
        bool pos = true;
        char c = getc();
        for (; (< '0' || c > '9') && c != '-'; c = getc()) {
            assert(~c);
        }
        if (== '-') {
            pos = false;
            c = getc();
        }
        for (; c >= '0' && c <= '9'; c = getc()) {
            ret = (ret << 3) + (ret << 1) + (^ 48);
        }
        return pos ? ret : -ret;
    }

    const int maxn = 200007;

    int n, m;
    int s, t;

    struct edge{
        int from,to;
        LL cap,flow;
    };

    map<int, int> vis;

    struct DINIC {
        int head[maxn << 1], nxt[maxn << 1], edge[maxn << 1], cnt;
        int cap[maxn << 1], depth[maxn << 1];

        void init() {
            cnt = 1;
            memset(head, 0, sizeof(head));
        }

        void BuildGraph(int u, int v, int w) {
            ++cnt;
            edge[cnt] = v;
            nxt[cnt] = head[u];
            cap[cnt] = w;
            head[u] = cnt;

            ++cnt;
            edge[cnt] = u;
            nxt[cnt] = head[v];
            cap[cnt] = 0;
            head[v] = cnt;
        }

        queue<int> q;

        bool bfs() {
            memset(depth, 0, sizeof(depth));
            depth[s] = 1;
            q.push(s);
            while(!q.empty()) {
                int u = q.front();
                q.pop();
                for ( int i = head[u]; i; i = nxt[i] ) {
                    int v = edge[i];
                    if(depth[v]) {
                        continue;
                    }
                    if(cap[i]) {
                        depth[v] = depth[u] + 1;
                        q.push(v);
                    }
                }
            }
            return depth[t];
        }

        int dfs(int u, int dist) {
            if(== t) {
                return dist;
            }
            int flow = 0;
            for ( int i = head[u]; i && dist; i = nxt[i] ) {
                if(cap[i] == 0)
                    continue;
                int v = edge[i];
                if(depth[v] != depth[u] + 1) {
                    continue;
                }
                int res = dfs(v, min(cap[i], dist));
                cap[i] -= res;
                cap[^ 1] += res;
                //printf("cap[%d]:%d ",t, cap[t]);
                vis[u] = v;
                dist -= res;
                flow += res;
            }
            return flow;
        }

        int maxflow() {
            int ans = 0;
            while(bfs()) {
                ans += dfs(s, inf);
            }
            return ans;
        }
    } dinic;

    int main()
    {
        //freopen("data.txt", "r", stdin);
        read(m); read(n); 
        int u, v;
        s = 0, t = n + m + 1;
        dinic.init();
        while(1) {
            read(u); read(v);
            if(== -1 && v == -1) {
                break;
            }
            dinic.BuildGraph(u, v, 1);
        }
        for ( int i = 1; i <= m; ++) {
            dinic.BuildGraph(s, i, 1);
        }
        for ( int i = m + 1; i <= m + n; ++) {
            dinic.BuildGraph(i, t, 1);
        }
        cout << dinic.maxflow() << endl;
        int tot = dinic.cnt;
        for ( int i = 2; i <= tot; i += 2 ) {
            int u = dinic.edge[i];
            int v = dinic.edge[^ 1];
            if(== s || u == t || v == s || v == t) {
                continue;
            }
            else {
                int cap = dinic.cap[^ 1];
                if(cap != 0) {
                    printf("%d %d ",v, u);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    C#如何生成CHM帮助文件
    使用WebBrowser控件播放Flash网页相关问题解决方法
    C# AnimateWindow与WindowState同时使用的效果
    C#读取计算机串口
    C#基础概念二十五个问题
    C# ini 文件读取方法
    JSP读出MYSQL数据库时的乱码问题解决方案
    世界编程大赛头名程序
    比较著名的.net技术论坛网址(含国外的)
    How to Install Linux, Apache, MySQL, PHP (LAMP) stack on CentOS 6
  • 原文地址:https://www.cnblogs.com/orangeko/p/12676474.html
Copyright © 2011-2022 走看看