USACO 4.2.1 Drainage Ditches 草地排水 ditch

This post is written in Chinese. Please consider using Google Translate

很明显的网络最大流问题,我用的是Edmonds-Karp算法实现的。 Edmonds-Karp 算法步骤

每次通过BFS,找到残余网络上从源点到汇点的一条最短增广路

在流网络上增加增广路

修改残余网络,残余容量减去增广路,并添加增广路的反向弧

当无法BFS到增广路时,算法结束

USER: CmYkRgB CmYkRgB [cmykrgb1]
TASK: ditch
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.000 secs, 3160 KB]
   Test 2: TEST OK [0.000 secs, 3156 KB]
   Test 3: TEST OK [0.000 secs, 3156 KB]
   Test 4: TEST OK [0.011 secs, 3160 KB]
   Test 5: TEST OK [0.000 secs, 3160 KB]
   Test 6: TEST OK [0.022 secs, 3156 KB]
   Test 7: TEST OK [0.000 secs, 3156 KB]
   Test 8: TEST OK [0.000 secs, 3160 KB]
   Test 9: TEST OK [0.011 secs, 3160 KB]
   Test 10: TEST OK [0.000 secs, 3160 KB]
   Test 11: TEST OK [0.011 secs, 3156 KB]
   Test 12: TEST OK [0.000 secs, 3160 KB]

All tests OK.


YOUR PROGRAM ('ditch') WORKED FIRST TIME!  That's fantastic
-- and a rare thing.  Please accept these special automated
congratulations.
/*
ID: cmykrgb1
PROG: ditch
LANG: C++
*/
#include <iostream>
#include <fstream>
#define MAX 201
using namespace std;

class Tadjl
{
public:
    class Tnode
    {
    public:
        int r,v;
        void set(int tr,int tv)
        {
            r=tr;
            v=tv;
        }
    };
    int cnt;
    Tnode link[MAX];
};

class tQueue
{
public:
    class linklist
    {
    public:
        linklist* next;
        int value;
        linklist()
        {
            next=0;
            value=0;
        }
    };
    linklist *first,*last;
    int size;
    void add(int p)
    {
        if (size==0)
            first=last=new linklist;
        else
            last=last->next=new linklist;
        last->value=p;
        size++;
    }
    int del()
    {
        int rtn=first->value;
        linklist *tfirst=first;
        first=first->next;
        delete tfirst;
        size--;
        return rtn;
    }
    void reset()
    {
        size=0;
        first=last=0;
    }
    tQueue()
    {
        reset();
    }
};

ifstream fi("ditch.in");
ofstream fo("ditch.out");

Tadjl adjl[MAX];
int N,M,ans;

inline int min(int a,int b)
{
    return a<b?a:b;
}

void init()
{
    int i,a,b,v;
    fi >> N >> M;
    for (i=1;i<=N;i++)
    {
        fi >> a >> b >> v;
        adjl[a].link[ ++adjl[a].cnt].set(b,v);
    }
}


int edmonds(int start,int end)
{
    int i,j,k;
    int father[MAX],fp[MAX],max[MAX];
    int Maxflow=0;
    memset(father,0,sizeof(father));
    max[start]=0x7FFFFFFF;
    tQueue *Q=new tQueue;
    Q->add(start);
    while (Q->size)
    {
        i=Q->del();
        for (k=1;k<=adjl[i].cnt;k++)
        {
            j=adjl[i].link[k].r;
            if (!adjl[i].link[k].v || j==start) continue;
            if (!father[j])
            {
                father[j]=i;
                fp[j]=k;
                max[j]=min(adjl[i].link[k].v,max[i]);
                if (j==end)
                {
                    Maxflow+=max[j];
                    while (father[j])
                    {
                        adjl[father[j]].link[fp[j]].v-=max[end];
                        adjl[j].link[++adjl[j].cnt].set(father[j],max[j]);
                        j=father[j];
                    }
                    memset(father,0,sizeof(father));
                    Q->reset();
                    Q->add(start);
                    break;
                }
                Q->add(j);
            }
        }
    }
    return Maxflow;
}

void print()
{
    fo << ans << endl;
    fi.close();
    fo.close();
}

int main()
{
    init();
    ans=edmonds(1,M);
    print();
    return 0;
}

Related posts