POJ1273 Drainage Ditches

一.原题链接:http://poj.org/problem?id=1273

二.题目大意:直接给边给容量让你求最大流,模板得不能再模板了。

三.思路:没有思路,直接套模板,我自己打的好吧。注意有重边,还有多组测试数据。

四.代码:

1.EK

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
#include <string>

using namespace std;

const int INF = 0x3f3f3f3f,
          MAX_N = 251, MAX_M = 208;

int capacity[MAX_N][MAX_N], N, M,
    flow[MAX_N][MAX_N];

int EK()
{
    int minFlow[MAX_N], preV[MAX_N], flag[MAX_N];
    int i, j, s, t, save, cur, res;
    queue <int> que;

    while(1){
        while(!que.empty())
            que.pop();
        memset(flag, -1, sizeof(flag));
        memset(preV, -1, sizeof(preV));
        que.push(1);
        s = 1, t = M;
        minFlow[1] = INF;

        while(!que.empty() && flag[t] == -1){
            cur = que.front(); que.pop();
            for(i = s; i <= t; i++){
                save = capacity[cur][i] - flow[cur][i];
                if(save > 0 && flag[i] == -1){
                    minFlow[i] = min(minFlow[cur], save);
                    flag[i] = 0;
                    que.push(i);
                    preV[i] = cur;
                }
            }
            flag[cur] = 1;
        }

        if(flag[t] == -1) break;
        for(i = preV[t], j = t; i != -1; j = i, i = preV[i]){
            flow[i][j] += minFlow[t];
            flow[j][i] = -flow[i][j];
        }
    }

    res = 0;
    for(i = s; i < t; i++)
        res += flow[i][t];
    return res;
}

int main()
{
    //freopen("in.txt", "r", stdin);

    int i, j, u, v, c;
    while(cin>>N>>M){
        memset(flow, 0, sizeof(flow));
        memset(capacity, 0, sizeof(capacity));

        for(i = 0; i < N; i++){
            cin>>u>>v>>c;
            capacity[u][v] += c;
        }

        cout<<EK()<<endl;
    }
}

2.Dinic (32ms)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
#include <string>

using namespace std;

const int INF = 0x3f3f3f3f,
          MAX_N = 251, MAX_M = 208;

int capacity[MAX_N][MAX_N], N, M,
    dist[MAX_N];

bool BFS()
{
    int i, cur;
    queue <int> que;
    memset(dist, -1, sizeof(dist));

    que.push(1);
    dist[1] = 0;
    while(!que.empty()){
        cur = que.front();
        que.pop();
        for(i = 1; i <= M; i++)
            if(capacity[cur][i] > 0 && -1 == dist[i]){
                dist[i] = dist[cur]+1;
                que.push(i);
            }
    }

    if(-1 == dist[M])
        return false;

    return true;
}

int DFS(int s, int minflow)
{
    int i, temp;
    if(s == M)
        return minflow;
    for(i = 1; i <= M; i++)
        if(dist[i] == dist[s] + 1 &&
           capacity[s][i] > 0 &&
           (temp = DFS(i, min(minflow, capacity[s][i])))){
               capacity[s][i] -= temp;
               capacity[i][s] += temp;
               return temp;
        }

    return 0;
}

int main()
{
    //freopen("in.txt", "r", stdin);

    int i, j, u, v, c, res, temp;
    while(cin>>N>>M){
        memset(capacity, 0, sizeof(capacity));

        for(i = 0; i < N; i++){
            cin>>u>>v>>c;
            capacity[u][v] += c;
        }

        res = 0;
        while(BFS()){
            while(temp = DFS(1, INF))
                res += temp;
        }
        cout<<res<<endl;
    }
}

3.预流推进(47ms)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
#include <string>

using namespace std;

const int INF = 0x3f3f3f3f,
          MAX_N = 251, MAX_M = 208;

int RE[MAX_M][MAX_M], N, M,
    maxFlow, H[MAX_M], EF[MAX_M];
queue <int> que;

void init()
{
    memset(RE, 0, sizeof(RE));
    memset(H, 0, sizeof(H));
    memset(EF, 0, sizeof(EF));
    maxFlow = 0;
    EF[1] = INF;
    EF[N] = -INF;
    H[1] = M;
}

void Push(int cur)
{
    int i, temp;
    for(i = 1; i <= M; i++){
        temp = min(EF[cur], RE[cur][i]);
        if(temp > 0 && (cur == 1 || H[cur] - H[i] == 1)){
            RE[cur][i] -= temp, RE[i][cur] += temp;
            EF[cur] -= temp, EF[i] += temp;
            if(i == M)
                maxFlow += temp;
            if(i != M && i != 1)
                que.push(i);
        }
    }
}

void Relabel(int cur)
{
    if(cur != 1 && cur != M && EF[cur] > 0){
        H[cur]++;
        que.push(cur);
    }
}

void Push_Relabel()
{
    int cur;
    que.push(1);
    while(!que.empty()){
        cur = que.front();
        que.pop();
        Push(cur);
        Relabel(cur);
    }
    cout<<maxFlow<<endl;
}

int main()
{
    //freopen("in.txt", "r", stdin);

    int i, j, u, v, c;
    while(cin>>N>>M){
        init();
        for(i = 0; i < N; i++){
            cin>>u>>v>>c;
            RE[u][v] += c;
        }

        Push_Relabel();
    }
}

4,最高标号预流推进(32ms)

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <cstdlib>

using namespace std;

const int INF = 0x3f3f3f3f,
          MAX_SIZE = 251;

class Push_Relabel
{
public:
    struct node
    {
        int x, h;
        bool friend operator <(const node &a,const node &b)
        {
            return a.h<b.h;
        }
    };

    struct Edge
    {
        int v, weigt, next;
    };

    Edge edges[MAX_SIZE*MAX_SIZE];
    int s, t, maxFlow, cnt,
        head[MAX_SIZE], H[MAX_SIZE], EF[MAX_SIZE];
    priority_queue <node> que;

    void init(int is, int it, int nodeNum)
    {
        memset(edges, 0, sizeof(edges));
        memset(H, 0, sizeof(H));
        memset(EF, 0, sizeof(EF));
        memset(head, -1, sizeof(head));
        maxFlow = 0;
        cnt = 0;
        s = is, t = it;
        EF[s] = INF;
        EF[t] = -INF;
        H[s] = nodeNum;
    }

    void addEdge(int u, int v, int weight)
    {
        edges[cnt] = (Edge){v, weight, head[u]};
        head[u] = cnt++;
        edges[cnt] = (Edge){u, 0, head[v]};
        head[v] = cnt++;
    }

    void Push(int cur)
    {
        int i, temp, v;
        node tmp;
        for(i = head[cur]; i != -1; i = edges[i].next){
            v = edges[i].v;
            temp = min(edges[i].weigt, EF[cur]);
            if(temp > 0 &&(cur == s || 1==H[cur]-H[v])){
                edges[i].weigt -= temp, edges[i^1].weigt += temp;
                EF[cur] -= temp, EF[v] += temp;
                if(v == t)
                    maxFlow += temp;
                if(v != s && v != t){
                    tmp.x = v, tmp.h = H[v];
                    que.push(tmp);
                }
            }
        }
    }

    void Relabel(int cur)
    {
        node tmp;
        if(cur != s && cur != t && EF[cur] > 0){
            H[cur]++;
            tmp.h = H[cur], tmp.x = cur;
            que.push(tmp);
        }
    }

    int ans()
    {
        node cur{s, H[s]};
        que.push(cur);
        while(!que.empty()){
            cur = que.top();
            que.pop();
            Push(cur.x);
            Relabel(cur.x);
        }
        return maxFlow;
    }
};

int nodeNum, edgeNum;
int getAns(int s, int t, int nodeNum)
{
    int i, j, u, v, c;
    Push_Relabel G;
    G.init(s, t, nodeNum);
    while(edgeNum--){
        cin>>u>>v>>c;
        G.addEdge(u, v, c);
    }
    return G.ans();
}

int main()
{
    //freopen("in.txt", "r", stdin);

    while(cin>>edgeNum>>nodeNum){

        cout<<getAns(1, nodeNum, nodeNum)<<endl;
    }
}

你可能感兴趣的:(POJ1273 Drainage Ditches)