【模板】网络最大流

充实的$one day$!泡了一下午图书馆,看了一节课泰勒展开,然后就复习了网络流。

一直以来觉得网络流只要有了建图思路就直接套板子跑就好了!于是这次没有很仔细地理解原理....

然后就是你谷数据又加强了,之前的ac代码跑不过了,需要在每次返回$res$的时候判断一下能否连通到汇点,不能的话下次就不跑它,优化一下。(或者应该说为什么以前没有优化过啊!!)

P3376 【模板】网络最大流


#include<bits/stdc++.h>

const int N = 10005;

using namespace std;

struct Node {
    int nex, v;
    Node(int nex = 0, int v = 0) :
        nex(nex), v(v) { }
} Edge[N << 1];

int stot = 1, h[N], f[N << 1];
void add(int u, int v, int w) {
    Edge[++stot] = Node(h[u], v);
    h[u] = stot;
    f[stot] = w;
}

bool vis[205];
int dis[205];
queue <int> q;

int n, s, t, m;
bool bfs() {
    memset(vis, 0, sizeof(vis));
    memset(dis, 0, sizeof(dis));
    q.push(s);    vis[s] = 1;
    while(!q.empty()) {
        int u = q.front();    q.pop();
        for(int i = h[u]; i; i = Edge[i].nex) {
            int v = Edge[i].v;
            if(!vis[v] && f[i]) {
                q.push(v);
                vis[v] = 1;
                dis[v] = dis[u] + 1;
            }
        }
    }
    return vis[t];
}

int dfs(int x, int delta) {
    if(x == t)    return delta;
    int res = 0;
    for(int i = h[x]; i; i = Edge[i].nex) {
        int v = Edge[i].v;
        if(f[i] && dis[v] == dis[x] + 1) {
            int dd = dfs(v, min(delta, f[i]));
            f[i] -= dd;
            f[i ^ 1] += dd;
            delta -= dd;
            res += dd;
        }
    }
    if(res == 0)    dis[x] = 0;
    return res;
}

int main() {
    scanf("%d%d%d%d", &n, &m, &s, &t);
    for(int i = 1; i <= m; i ++) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        add(u, v, w);    add(v, u, 0);
    }
    long long ans = 0;
    while(bfs())
        ans += dfs(s, 0x3f3f3f3f);
    printf("%lld", ans);
    return 0;
}

今天还发现了一个很憨的事,$Abyssful$在18年考前把我的板子几乎全复制粘贴到他的$blog$了!!居然感想都一点没改!!(我看前几篇当时还没觉得不对,直到翻到一个刚看过的板子,才发现他平时说话风格就和我好像aaa!!!×)估计是搜索关键字“模板”来的吧!我是不是可以告他侵权,或者让他赔偿一点(很多)版权费?在线等优质回答。

posted @ 2020-11-07 20:01  Wans_ovo  阅读(126)  评论(1编辑  收藏  举报