zoukankan      html  css  js  c++  java
  • 网络流24题(更新中

    看着别人写网络流24题题解,有点小羡慕,所以照着也来一个网络流24题题解.

    2018-08-18 网络流从零开始入门.

    ----------------------------------------2018-08-18-----------------------------------------------

    ----------------------------------------2018-08-19-----------------------------------------------

    凉凉  开门脆, 直接鸽了2天= =.

    ----------------------------------------2018-08-20-----------------------------------------------

    ----------------------------------------2018-08-21-----------------------------------------------

    咕咕咕  鸽子愉快的第四天生活. 美滋滋

    咕咕咕 咕咕咕 咕咕咕 咕咕咕 咕咕咕 咕咕咕 咕咕咕 咕咕咕 咕咕咕 咕咕咕

    (为了清除罪恶感,以上咕咕咕都为手打,绝无粘贴复制 23333 ) 

    OK 我们来开始网络流的第一道题.

    1. 飞行员配对方案问题  (二分图模型.

    https://www.luogu.org/problemnew/show/P2756

    很明显 这是裸的二分图, 所以直接套一个二分图板子就A了...emmmmmmmmmmmm ???????????网络流呢?? 不存在的...明明可以简单二分图干嘛要网络流...(毕竟我还不会 hhhhhh

    #include <vector>
    #include <queue> 
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 100024;
    
    struct nobe {
        int to;
        int lst;
    }edge[maxn];
    int head[128];
    int qsz = 1;
    
    inline void add(int u, int v) {
        edge[qsz].lst = head[u];
        edge[qsz].to  = v;
        head[u] = qsz++;    
    }
    
    int matching[128];
    bool check[128];
    
    bool dfs(int u) {
        int i, v;
        for (i=head[u]; i; i=edge[i].lst) {
            v = edge[i].to;
            if (!check[v]) {
                check[v] = true;
                if (matching[v]==-1 || dfs(matching[v])) {
                    matching[v] = u;
                    matching[u] = v;
                    return true;
                }
            }
        }
        return false;
    }
    
    int GetAns(int n) {
        int ans = 0;
        memset(matching, -1, sizeof(matching));
        for (int i=1; i<=n; ++i) {
            if (matching[i] == -1) {
                memset(check, 0, sizeof(check));
                ans += dfs(i);
            }
        }
        return ans;
    }
    
    int main()
    {
        int n, m;
        scanf("%d%d", &m, &n);
        int u, v;
        while (scanf("%d%d", &u, &v) && (u!=-1 || v!=-1))  
            add(u, v);
        
        printf("%d
    ", GetAns(m));
        for (int i=1; i<=m; ++i) if (matching[i] != -1) printf("%d %d
    ", i, matching[i]);
        
        return 0;
    }
    View Code

    这道题我直接用dfs写法,,emmm 还有更加优秀的bfs写法, 然后有一个优秀的二分图博客(匈牙利)讲解得贼棒.(32ms)

    就是这个博客 http://blog.jobbole.com/106084/#article-comment   由浅入深,娓娓道来, 让人感到 波澜起伏 惊心动魄 扣人心弦 欲罢不能 叹为观止, 惊天动地. (好的,以上成语皆为百度提供.: 搜索 形容讲得非常好的成语

    好的 接下来的网络流做法...等...等我再补.  2018-8-21

     好的 这是二分图的bfs写法.  (23ms)  ZZ了把数据类型写错了...调了一个多小时...

    #include <vector>
    #include <queue> 
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 100024;
    
    struct nobe {
        int to;
        int lst;
    }edge[maxn];
    int head[128];
    int qsz = 1;
    
    inline void add(int u, int v) {
        edge[qsz].lst = head[u];
        edge[qsz].to  = v;
        head[u] = qsz++;    
    }
    
    int match[128];
    int vis[128];
    int prevv[128];
    
    int bfs(int m) {
        queue<int> Q;
        int i, j, u, v, ans = 0;
        memset(match, -1, sizeof(match));
        memset(vis, -1, sizeof(vis));
        for (i=1; i<=m; ++i) {
            if (match[i] == -1) {
                while (!Q.empty()) Q.pop();
                Q.push(i);
                prevv[i] = -1;
                bool flag = false;
                while (!Q.empty() && !flag) {
                    u = Q.front();
                    for (j=head[u]; j && !flag; j=edge[j].lst) {
                    
                        v = edge[j].to;
                        if (vis[v] != i) {
                            vis[v] = i;
                            Q.push(match[v]);
                            if (match[v] >= 0) {
                                prevv[match[v]] = u;
                            } else {
                                flag = true;
                                int d = u, e = v;
                                while (d != -1) {
                                    int t = match[d];
                                    match[d] = e;
                                    match[e] = d;
                                    d = prevv[d];
                                    e = t;
                                }
                            }
                        }
                    }
                    Q.pop();
                }
                if (match[i] != -1) ans++;
            }
        }
        return ans;
    } 
    
    int main()
    {
        int n, m;
        scanf("%d%d", &m, &n);
        int u, v;
        while (scanf("%d%d", &u, &v) && (u!=-1 || v!=-1))  
            add(u, v);
        
        printf("%d
    ", bfs(m));
        for (int i=1; i<=m; ++i) if (match[i] != -1) printf("%d %d
    ", i, match[i]);
        
        return 0;
    }
    View Code

    ----------------------------------------2018-08-22-----------------------------------------------

    咕咕咕,学习效率太慢了..二分图原理还不是很多..

    感觉最大匹配数分好几种,变个型就不会了.  匈牙利算法- -.

    无向图最大匹配数, DAG最大匹配数,二分图最大匹配数,写法都有所不同...但是原理没搞懂啊...

    ----------------------------------------2018-08-23-----------------------------------------------

  • 相关阅读:
    asp.net textbox 控件如何清除缓存
    extjs Accordion 怎样把展开符号:加号(+)放在左边?
    ORACLE 调试输出,字符串执行函数
    Oracle中table函数的应用
    Oracle LAST_DAY(d)
    Oracle 管道化表函数(Pipelined Table)[转载]
    ext中fieldLabel文本太宽的问题,以及Panel居中显示
    什么是泛型(C#)
    设置Ext tab的宽度自动适应
    js选择日期即时把两个日期相差天数显示出来?
  • 原文地址:https://www.cnblogs.com/cgjh/p/9496623.html
Copyright © 2011-2022 走看看