1. 程式人生 > >Drainage Ditches(最大流)

Drainage Ditches(最大流)

題目連結

最大流的模板題。。

多動手模擬,有一個講的很清楚的部落格:傳送門

聽說EK容易TLE。

EK:

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 210;
int n, m, c[N][N], pre[N], mmin;

bool bfs(int s, int t){
    memset(pre, -1, sizeof pre);
    pre[s] = 0;
    queue<int> que;
    mmin = INF;
    que.push(s);
    while
(!que.empty()){ int x = que.front(); que.pop(); for(int i = 1; i <= m; ++i){ if(c[x][i] > 0 && pre[i] == -1){ pre[i] = x; mmin = min(mmin, c[x][i]); if(i == t) return true; que.push(i); } } } if
(pre[t] != -1) return true; else return false; } void EdmondsKarp(int s, int t){ int sum = 0; while(bfs(s,t)){ sum += mmin; int x = t; while(x){ c[pre[x]][x] -= mmin; c[x][pre[x]] += mmin; x = pre[x]; } } printf
("%d\n", sum); } int main(int argc, char const *argv[]) { while(scanf("%d %d", &n, &m) != EOF){ memset(c, 0, sizeof c); int a, b, r; for(int i = 1; i <=n; ++i){ a = read(); b = read(); r = read(); if(a == b) continue; c[a][b] += r; } EdmondsKarp(1, m); } return 0; }

Dinic:

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 300;

struct EDGE {
    int u, v, cap;
    EDGE(int u=0,int v=0,int cap=0):u(u),v(v),cap(cap){};
};

int dis[N], cur[N], V, E, S, T; //V點E邊S起點T終點
vector<int> G[N];
vector<EDGE> edge;

void add(int u, int v, int cap) {
    edge.push_back((EDGE){
        u, v, cap
    });
    edge.push_back((EDGE){
        v, u, 0
    });
    int size = edge.size();
    G[u].push_back(size - 2);
    G[v].push_back(size - 1);
}

bool bfs(){
    memset(dis, 0, sizeof dis);
    queue<int> que;
    que.push(S); dis[S] = 1;
    while(!que.empty()){
        int x = que.front(); que.pop();
        int size = (int)G[x].size();
        for(int i = 0; i < size; ++i){
            EDGE& e = edge[G[x][i]];
            if(e.cap > 0 && !dis[e.v]){
                dis[e.v] = dis[e.u] + 1;
                que.push(e.v);
            }
        }
    }
    return dis[T];
}

int dfs(int x, int maxflow){
    if(x == T || !maxflow)  return maxflow;
    int flow = 0, delta;
    int size = (int)G[x].size();
    for(int& i = cur[x]; i < size; ++i){
        EDGE& e = edge[G[x][i]];
        if(dis[e.v] == dis[x] + 1){
            delta = dfs(e.v, min(maxflow, e.cap));
            if(delta > 0){
                e.cap -= delta;
                edge[G[x][i]^1].cap += delta;
                flow += delta;
                maxflow -= delta;
                if(!maxflow)    break;
            }
        }
    }
    return flow;
}

void dinic(){
    int ans = 0;
    while(bfs()){
        memset(cur, 0, sizeof cur);
        ans += dfs(S, INF);
    }
    printf("%d\n", ans);
}

int main(int argc, char const *argv[])
{
    int a, b, val;
    while(scanf("%d %d", &E, &V) != EOF){
        S = 1; T = V;
        edge.clear();
        for(int i=0;i<=V;++i)   G[i].clear();
        while(E--){
            scanf("%d %d %d", &a, &b, &val);
            if(a == b)  continue;
            add(a, b, val);
        }
        dinic();
    }
    return 0;
}