zoukankan      html  css  js  c++  java
  • 网络流复习笔记

    网络流的空间要好好算!!!

    不然就各种出事。。。

    混合图的欧拉回路

    没有账号,懂个思路就好了

    [POI2010]MOS-Bridges

    看起来是前面那题多了个二分,待会去敲一敲

     

    感觉自己最小割怎么跟没学过一样,摘了个oi-wiki上的模型

    拍照

    乍一看怎么和太空飞行计划一模一样

    确实是一样的233

    但怎么我之前会现在就连这个都不会了,药丸药丸

    自闭了

    文理分科

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 30010, M = 280010;
    
    int n, m, a[110][110], s[110][110], sa[110][110], ss[110][110], id[110][110], tot, sum;
    
    int head[N], to[M], nxt[M], edge[M], cnt = 1, st, ed, h[N];
    
    void add_edge(int u, int v, int w) {
        to[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt;
    }
    
    void addedge(int u, int v, int w) {
        add_edge(u, v, w), add_edge(v, u, 0);
    }
    
    queue<int> q; int d[N];
    
    bool bfs() {
        while (q.size()) q.pop();
        for (int i = 0; i <= ed; i++) d[i] = 0, h[i] = head[i];
        q.push(st), d[st] = 1;
        while (q.size()) {
            int u = q.front(); q.pop();
            for (int i = head[u]; i; i = nxt[i]) {
                int v = to[i];
                if (edge[i] && !d[v]) {
                    d[v] = d[u] + 1;
                    if (v == ed) return true;
                    q.push(v);
                }
            }
        }
        return false;
    }
    
    int dinic(int u, int flow) {
        if (u == ed) return flow;
        int rest = flow, now;
        for (int &i = h[u]; i; i = nxt[i]) {
            int v = to[i];
            if (edge[i] && d[v] == d[u] + 1) {
                now = dinic(v, min(edge[i], rest));
                //if (!now) d[v] = -1;
                edge[i] -= now, edge[i ^ 1] += now, rest -= now;
            }
        }
        return flow - rest;
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]), id[i][j] = ++tot, sum += a[i][j];
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) scanf("%d", &s[i][j]), sum += s[i][j];
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) scanf("%d", &sa[i][j]), sum += sa[i][j];
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) scanf("%d", &ss[i][j]), sum += ss[i][j];
        st = 0, ed = tot * 3 + 1;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                addedge(st, id[i][j], a[i][j]), addedge(id[i][j], ed, s[i][j]);
                int x = tot + id[i][j], y = x + tot;
                addedge(st, x, sa[i][j]), addedge(y, ed, ss[i][j]);
                addedge(x, id[i][j], 0x3f3f3f3f), addedge(id[i][j], y, 0x3f3f3f3f);
                if (i > 1) addedge(x, id[i - 1][j], 0x3f3f3f3f), addedge(id[i - 1][j], y, 0x3f3f3f3f);
                if (j > 1) addedge(x, id[i][j - 1], 0x3f3f3f3f), addedge(id[i][j - 1], y, 0x3f3f3f3f);
                if (i < n) addedge(x, id[i + 1][j], 0x3f3f3f3f), addedge(id[i + 1][j], y, 0x3f3f3f3f);
                if (j < m) addedge(x, id[i][j + 1], 0x3f3f3f3f), addedge(id[i][j + 1], y, 0x3f3f3f3f);
            }
        }
        int maxflow = 0, flow = 0;
        while (bfs()) while (flow = dinic(st, 0x3f3f3f3f)) maxflow += flow;
        cout << sum - maxflow << endl;
        return 0;
    } 
    View Code

    芯片难题 Chips Challenge

     

    无源汇有上下界可行流

    #include <bits/stdc++.h>
    
    using namespace std;
    
    
    inline int read() {
        int out = 0; bool flag = false;
        register char cc = getchar();
        while (cc < '0' || cc > '9') {
            if (cc == '-') flag = true;
            cc = getchar();
        }
        while (cc >= '0' && cc <= '9') {
            out = (out << 3) + (out << 1) + (cc ^ 48);
            cc = getchar();
        } 
        return flag ? -out : out;
    }
    
    inline void write(int x, char ch) {
        if (x < 0) putchar('-'), x = -x;
        if (x == 0) putchar('0');
        else {
            int num = 0; char cc[22];
            while (x) cc[++num] = x % 10 + 48, x /= 10;
            while (num) putchar(cc[num--]);
        }
        putchar(ch);
    }
    
    const int N = 210, M = 42000;
    
    int n, m, s, t, inf[N], outf[N], dow[M];
    
    int head[N], to[M], nxt[M], edge[M], cnt = 1, h[N];
    
    void add_edge(int u, int v, int w) {
        to[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt;
    }
    
    void addedge(int u, int v, int w) {
        add_edge(u, v, w), add_edge(v, u, 0);
    }
    
    queue<int> q; int d[N];
    
    bool bfs() {
        while (q.size()) q.pop();
        for (int i = 0; i <= t; i++) d[i] = 0, h[i] = head[i];
        q.push(s), d[s] = 1;
        while (q.size()) {
            int u = q.front(); q.pop();
            for (int i = head[u]; i; i = nxt[i]) {
                int v = to[i];
                if (edge[i] && !d[v]) {
                    d[v] = d[u] + 1;
                    if (v == t) return true;
                    q.push(v);
                }
            }
        }
        return false;
    }
    
    int dinic(int u, int flow) {
        if (u == t) return flow;
        int rest = flow, now;
        for (int &i = h[u]; i; i = nxt[i]) {
            int v = to[i];
            if (edge[i] && d[v] == d[u] + 1) {
                now = dinic(v, min(rest, edge[i]));
                edge[i] -= now, edge[i ^ 1] += now, rest -= now;
            }
        }
        return flow - rest;
    }
    
    int main() {
        n = read(), m = read();
        s = 0, t = n + 1;
        for (int i = 1; i <= m; i++) {
            int u = read(), v = read(), down = read(), up = read(); 
            outf[u] += down, inf[v] += down, dow[i] = down, addedge(u, v, up - down);
        }
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            if (inf[i] > outf[i]) addedge(s, i, inf[i] - outf[i]);
            if (inf[i] < outf[i]) addedge(i, t, outf[i] - inf[i]);
        }
        while (bfs()) dinic(s, 0x3f3f3f3f);
        bool flag = false;
        for (int i = head[s]; i; i = nxt[i]) if (!(i & 1)) flag |= (edge[i] != 0);
        if (flag) puts("NO");
        else {
            puts("YES");
            for (int i = 2; i <= (m << 1); i += 2) write(dow[i >> 1] + edge[i ^ 1], '
    ');
        }
        return 0;
    } 
    View Code

     

    [AHOI2014/JSOI2014]支线剧情

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 310, M = 12000;
    
    int n, k, f[310], s, t, S, T, ans;
    
    int head[N], to[M], nxt[M], edge[M], cst[M], cnt = 1, h[N];
    
    void add_edge(int u, int v, int w, int c) {
        to[++cnt] = v, edge[cnt] = w, cst[cnt] = c;
        nxt[cnt] = head[u], head[u] = cnt;
    }
    
    void addedge(int u, int v, int w, int c) {
        add_edge(u, v, w, c), add_edge(v, u, 0, -c);
    }
    
    queue<int> q; int dis[N]; bool vis[N];
    
    bool spfa() {
        for (int i = 0; i <= T; i++) dis[i] = 0x3f3f3f3f, vis[i] = false, h[i] = head[i];
        q.push(S), dis[S] = 0;
        while (q.size()) {
            int u = q.front(); q.pop();
            vis[u] = false;
            for (int i = head[u]; i; i = nxt[i]) {
                int v = to[i];
                if (edge[i] && dis[v] > dis[u] + cst[i]) {
                    dis[v] = dis[u] + cst[i];
                    if (!vis[v]) vis[v] = true, q.push(v);
                }
            }
        }
        return dis[T] != 0x3f3f3f3f;
    } 
    
    int dinic(int u, int flow) {
        if (u == T) return flow;
        int rest = flow, now;
        vis[u] = true;
        for (int &i = h[u]; i; i = nxt[i]) {
            int v = to[i];
            if (!vis[v] && edge[i] && dis[v] == dis[u] + cst[i]) {
                now = dinic(v, min(rest, edge[i]));
                edge[i] -= now, edge[i ^ 1] += now, rest -= now;
                ans += now * cst[i];
            }
        }
        vis[u] = false;
        return flow - rest;
    }
    
    int main() {
        scanf("%d", &n);
        s = 1, t = n + 1, S = 0, T = n + 2;
        for (int u = 1; u <= n; u++) {
            scanf("%d", &k);
            for (int j = 1; j <= k; j++) {
                int v, c; scanf("%d%d", &v, &c);
                f[u]--, f[v]++, addedge(u, v, 0x3f3f3f3f, c), ans += c;
            }
            addedge(u, t, 0x3f3f3f3f, 0);
        }
        for (int i = 1; i <= n; i++) {
            if (f[i] > 0) addedge(S, i, f[i], 0);
            if (f[i] < 0) addedge(i, T, -f[i], 0);
        }
        addedge(t, s, 0x3f3f3f3f, 0);
        while (spfa()) dinic(S, 0x3f3f3f3f);
        cout << ans << endl;
        return 0;
    }
    View Code

    [NEERC2016]Mole Tunnels

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n, m, c[100010], u, pos[100010], dis[100010], fa[100010], ls[100010], rs[100010], ans;
    
    void dfs(int u) {
        if (u > n) return ;
        dfs(u << 1), dfs(u << 1 | 1);
        if (c[u]) dis[u] = 0, pos[u] = u;
        else dis[u] = 0x3f3f3f3f, pos[u] = -1;
        if ((u << 1) <= n && dis[u] > dis[u << 1] + 1) dis[u] = dis[u << 1] + 1, pos[u] = pos[u << 1];
        if ((u << 1 | 1) <= n && dis[u] > dis[u << 1 | 1] + 1) dis[u] = dis[u << 1 | 1] + 1, pos[u] = pos[u << 1 | 1];
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
        dfs(1);
        for (int i = 1; i <= m; i++) {
            scanf("%d", &u);
            int now = u, s = 0, res = 0x3f3f3f3f, v = -1;
            while (now) {
                if (res > s + dis[now]) res = s + dis[now], v = now;
                if (fa[now] > 0) s -= 1;
                else s += 1;
                now >>= 1;
            }
            printf("%d ", ans += res);
            now = v, v = pos[v];
            c[v]--;
            while (v != now) {
                int ff = v >> 1;
                if (v == (ff << 1)) {
                    if (ls[ff] > 0) ls[ff]--;
                    else fa[v]++;
                }  
                else {
                    if (rs[ff] > 0) rs[ff]--;
                    else fa[v]++;
                }
                if (c[v]) dis[v] = 0, pos[v] = v;
                else dis[v] = 0x3f3f3f3f, pos[v] = -1;
                if ((v << 1) <= n && dis[v] > dis[v << 1] + (ls[v] ? -1 : 1)) dis[v] = dis[v << 1] + (ls[v] ? -1 : 1), pos[v] = pos[v << 1];
                if ((v << 1 | 1) <= n && dis[v] > dis[v << 1 | 1] + (rs[v] ? -1 : 1)) dis[v] = dis[v << 1 | 1] + (rs[v] ? -1 : 1), pos[v] = pos[v << 1 | 1];
                v = ff;
            }
            while (u != now) {
                if (fa[u]) fa[u]--;
                else {
                    if (((u >> 1) << 1) == u) ls[u >> 1]++;
                    else rs[u >> 1]++;
                }
                if (c[u]) dis[u] = 0, pos[u] = u;
                else dis[u] = 0x3f3f3f3f, pos[u] = -1;
                if ((u << 1) <= n && dis[u] > dis[u << 1] + (ls[u] ? -1 : 1)) dis[u] = dis[u << 1] + (ls[u] ? -1 : 1), pos[u] = pos[u << 1];
                if ((u << 1 | 1) <= n && dis[u] > dis[u << 1 | 1] + (rs[u] ? -1 : 1)) dis[u] = dis[u << 1 | 1] + (rs[u] ? -1 : 1), pos[u] = pos[u << 1 | 1];
                u >>= 1;
            }
            while (now) {
                if (c[now]) dis[now] = 0, pos[now] = now;
                else dis[now] = 0x3f3f3f3f, pos[now] = -1;
                if ((now << 1) <= n && dis[now] > dis[now << 1] + (ls[now] ? -1 : 1)) dis[now] = dis[now << 1] + (ls[now] ? -1 : 1), pos[now] = pos[now << 1];
                if ((now << 1 | 1) <= n && dis[now] > dis[now << 1 | 1] + (rs[now] ? -1 : 1)) dis[now] = dis[now << 1 | 1] + (rs[now] ? -1 : 1), pos[now] = pos[now << 1 | 1];
                now >>= 1;
            }
        }
        return 0;
    } 
    View Code

     

  • 相关阅读:
    select应用于read函数 超时非阻塞方式
    取文本索引所执向的值(简单)
    linux c函数指针的应用
    解决vsftp无法启动问题(转)
    Could not chdir to home directory /home/USER: Permission denied
    sscanf和正则表达式
    存储过程重置SEQUENCE值从新开始。
    Signal ()函数详细介绍 Linux函数(转)
    linux 环境NTP配置与开机自启动(转)
    linux下iconv()函数的用法(转载并修改)
  • 原文地址:https://www.cnblogs.com/Urushibara-Ruka/p/14515477.html
Copyright © 2011-2022 走看看