POJ 1273 Drainage Ditches

来源:互联网 发布:模拟投资软件 编辑:程序博客网 时间:2024/06/02 02:37

题意

给m个点(窝巢!),n条边的有向图,求1~m最大流

题解

测试最大流模板(尼玛又是m个点)

code

Dinic

#include <algorithm>#include <bitset>#include <cassert>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <deque>#include <iostream>#include <map>#include <queue>#include <set>#include <string>#include <vector>const int INF = 0x3f3f3f3f;const int MAXN = 20010;const int MAXM = 100010;struct Dinic {    int n, tot, s, t;    int st[MAXN], st0[MAXN];    int lk[MAXM << 1], b[MAXM << 1], f[MAXM << 1]; bool del[MAXM << 1];    int Q[MAXN]; int l, r;    int d[MAXN];    void init() {        memset(st, 0, sizeof st); tot = 1;    }    void addedge(int u, int v, int w) {        lk[++ tot] = st[u]; b[tot] = v; f[tot] = w; del[tot] = 0; st[u] = tot;        lk[++ tot] = st[v]; b[tot] = u; f[tot] = 0; del[tot] = 0; st[v] = tot;    }    bool BFS() {        memset(d, 0, sizeof d);        l = r = 0;        d[ Q[r ++] = s ] = 1;        for (; l != r; ++ l) {            int u = Q[l];            for (int i = st[u]; i; i = lk[i]) if (!del[i]) {                int v = b[i];                if (f[i] && !d[v]) {                    d[v] = d[u] + 1;                    Q[r ++] = v;                }            }        }        return d[t];    }    int DFS(int u, int a) {        if (u == t || a == 0) return a;        int flow = 0, df;        for (int& i = st0[u]; i; i = lk[i]) if (!del[i]) {            int v = b[i];            if (d[v] == d[u] + 1 && (df = DFS(v, std::min(a, f[i])))) {                f[i] -= df; f[i^1] += df;                a -= df; flow += df;                if (a == 0) break;            }        }        return flow;    }    void solve(int s, int t, int& flow) {        this->s = s; this->t = t;        while (BFS()) {            memcpy(st0, st, sizeof st0);            flow += DFS(s, INF);        }    }    void dt(int e) {        del[e] = del[e^1] = 1;    }    void aug(int s, int t, int& flow) {        this->s = s; this->t = t;        if (BFS()) {            memcpy(st0, st, sizeof st0);            flow += DFS(s, 1);        }    }} solver;const int maxm = 10010;int n, m, s, t;int a[maxm];int lst[maxm];bool solve() {    if (!(scanf("%d%d", &m, &n) == 2)) return 0;    solver.init();    for (int i = 1; i <= m; ++ i) {        int u, v, w; scanf("%d%d%d", &u, &v, &w);        solver.addedge(u, v, w);    }    int flow = 0;    solver.solve(1, n, flow);    printf("%d\n", flow);    return 1;}int main() {//  freopen("poj1273.in", "r", stdin);    while (solve());//  for(;;);    return 0;}

SAP(貌似可能有小问题。。。后面找到了回来改。。)

#include <algorithm>#include <bitset>#include <cassert>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <deque>#include <iostream>#include <map>#include <queue>#include <set>#include <string>#include <vector>const int INF = 0x3f3f3f3f;const int MAXN = 20010;const int MAXM = 100010;struct SAP {    int n, tot, s, t;    int st[MAXN], st0[MAXN];    int lk[MAXM << 1], b[MAXM << 1], f[MAXM << 1]; bool del[MAXM << 1];    int Q[MAXN]; int l, r;//  int d[MAXN];    void init(int n) {        this->n = n;        memset(st, 0, sizeof st); tot = 1;    }    void addedge(int u, int v, int w) {        lk[++ tot] = st[u]; b[tot] = v; f[tot] = w; del[tot] = 0; st[u] = tot;        lk[++ tot] = st[v]; b[tot] = u; f[tot] = 0; del[tot] = 0; st[v] = tot;    }    int vh[MAXN], h[MAXN];    int DFS(int u, int a) {        if (u == t || a == 0) return a;        int flow = 0, df;        for (int& i = st0[u]; i; i = lk[i]) if (!del[i]) {            int v = b[i];            if (f[i] && h[u] == h[v]+1) {                df = DFS(v, std::min(a, f[i]));                f[i] -= df; f[i^1] += df;                a -= df; flow += df;                if (h[s] == n || a == 0) return flow;            }        }        int minh = n;        for (int i = st0[u] = st[u]; i; i = lk[i]) if (!del[i]) {            int v = b[i];            if (f[i] && h[v]+1 < minh) minh = h[v]+1;        }        if (!(-- vh[h[u]])) h[s] = n; else ++ vh[h[u] = minh];        return flow;    }    void solve(int s, int t, int& flow) {        this->s = s; this->t = t;        memset(h, 0, sizeof h);        memset(vh, 0, sizeof vh);        vh[0] = n;        memcpy(st0, st, sizeof st0);        while (h[s] < n)            flow += DFS(s, INF);    }    void dt(int e) {        del[e] = del[e^1] = 1;    }} solver;const int maxm = 10010;int n, m, s, t;int a[maxm];int lst[maxm];bool solve() {    if (!(scanf("%d%d", &m, &n) == 2)) return 0;    solver.init(n);    for (int i = 1; i <= m; ++ i) {        int u, v, w; scanf("%d%d%d", &u, &v, &w);        solver.addedge(u, v, w);    }    int flow = 0;    solver.solve(1, n, flow);    printf("%d\n", flow);    return 1;}int main() {//  freopen("poj1273.in", "r", stdin);    while (solve());//  for(;;);    return 0;}

ISAP(非递归式)

#include <algorithm>#include <bitset>#include <cassert>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <deque>#include <iostream>#include <map>#include <queue>#include <set>#include <string>#include <vector>using namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 20010;const int MAXM = 100010;struct ISAP {    int n, tot, s, t;    int st[MAXN], st0[MAXN];    int lk[MAXM << 1], b[MAXM << 1], f[MAXM << 1]; bool del[MAXM << 1];    int Q[MAXN]; int l, r;    int d[MAXN], p[MAXN];    int num[MAXN];    void init(int n) { // all indices should < n        this->n = n;        memset(st, 0, sizeof st); tot = 1;    }    void addedge(int u, int v, int w) {        lk[++ tot] = st[u]; b[tot] = v; f[tot] = w; del[tot] = 0; st[u] = tot;        lk[++ tot] = st[v]; b[tot] = u; f[tot] = 0; del[tot] = 0; st[v] = tot;    }    bool BFS() {        memset(d, 255, sizeof d);        l = r = 0;        d[ Q[r ++] = t ] = 0;        for (; l != r; ++ l) {            int u = Q[l];            for (int i = st[u]; i; i = lk[i]) {                int v = b[i];                if (f[i^1] && !~d[v]) {//                  d[v] = d[u] + 1;                    d[v] = 0;                    Q[r ++] = v;                }            }        }        return ~d[s];    }    int augment() {        int a = INF;        for (int u = t; u != s; ) {            int i = p[u];            a = min(a, f[i]);            u = b[i^1];        }        for (int u = t; u != s; ) {            int i = p[u];            f[i] -= a; f[i^1] += a;            u = b[i^1];        }        return a;    }    void solve(int s, int t, int& flow) {        this->s = s; this->t = t;        BFS();        memset(num, 0, sizeof num);        for (int i = 0; i < n; ++ i) if (~d[i]) ++ num[d[i]]; else ++ num[0];        memcpy(st0, st, sizeof st0);        for (int u = s; d[s] < n; ) {            if (u == t) {                flow += augment();                u = s;//              printf("%d\n", flow);//              for (int i = 0; i <= 10; ++ i) printf("%d ", num[i]); putchar('\n');                if (flow == 54407) {                    int pp = 1;                }//              BFS();            }            int ok = 0;            for (int& i = st0[u]; i; i = lk[i]) {                int v = b[i];                if (f[i] && d[u] == d[v] + 1) {                    ok = 1;                    p[v] = i;                    u = v;                    break;                }            }            if (!ok) {                int mn = n-1;                for (int i = st0[u] = st[u]; i; i = lk[i]) {                    int v = b[i];                    if (f[i] && d[v] < mn) mn = d[v];                }                if ((-- num[d[u]]) == 0) break;                ++ num[ d[u] = mn+1 ];                if (u != s)                    u = b[p[u]^1];            }        }    }} solver;int n, m, s, t;bool solve() {    if (!(scanf("%d%d", &m, &n) == 2)) return 0;    solver.init(n+1);    for (int i = 1; i <= m; ++ i) {        int u, v, w; scanf("%d%d%d", &u, &v, &w);        solver.addedge(u, v, w);    }    int flow = 0;    solver.solve(1, n, flow);    printf("%d\n", flow);    return 1;}int main() {//  freopen("poj1273.in", "r", stdin);//  freopen("poj1273.out", "w", stdout);    while (solve());//  for(;;);    return 0;}
0 0
原创粉丝点击