网络流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\n", GetAns(m));
    for (int i=1; i<=m; ++i) if (matching[i] != -1) printf("%d %d\n", 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\n", bfs(m));
    for (int i=1; i<=m; ++i) if (match[i] != -1) printf("%d %d\n", i, match[i]);
    
    return 0;
}
View Code

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

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

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

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

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

posted @ 2018-08-21 20:33  过路人1998  阅读(130)  评论(0编辑  收藏  举报