poj 1273 Drainage Ditches(最大流)

http://poj.org/problem?id=1273

Drainage Ditches
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 62708   Accepted: 24150

Description

Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage ditches so that Bessie's clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch. 
Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network. 
Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle. 

Input

The input includes several cases. For each case, the first line contains two space-separated integers, N (0 <= N <= 200) and M (2 <= M <= 200). N is the number of ditches that Farmer John has dug. M is the number of intersections points for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.

Output

For each case, output a single integer, the maximum rate at which water may emptied from the pond.

Sample Input

5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10

Sample Output

50

题目大意:m条边,每条边都有一个流量值,n个点,求1到n的最大流量

Dinic模板:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
#define N 210
#define INF 0x3f3f3f3f

using namespace std;

int G[N][N], vis[N], layer[N];
int n;

bool BFS()//分层处理
{
    deque<int>Q;//定义双端队列
    memset(layer, -1, sizeof(layer));
    Q.push_back(1);//源点入队列(双端队列尾部增加一个元素x)
    layer[1] = 1;//标记源点
    while(!Q.empty())
    {
        int u = Q.front(), i;
        Q.pop_front();//删除双端队列中最前一个元素
        for(i = 1 ; i <= n ; i++)//遍历点判断是否能分层
        {
            if(G[u][i] > 0 && layer[i] == -1)//当u点到i点这条边有流量且i点尚未被分层
            {
                layer[i] = layer[u] + 1;//则将i点分层
                if(i == n)//当到达汇点时分层成功
                    return true;
                else
                    Q.push_back(i);//否则继续
            }
        }
    }
    return false;
}

int Dinic()
{
    int Maxflow = 0;
    while(BFS() == true)
    {
        deque<int>Q;
        memset(vis, 0, sizeof(vis));
        Q.push_back(1);
        vis[1] = 1;
        while(!Q.empty())
        {
            int v = Q.back(), i;
            if(v != n)
            {
                for(i = 1 ; i <= n ; i++)
                {
                    if(G[v][i] > 0 && layer[v] + 1 == layer[i] && !vis[i])//如果v到i有流量且i点是v点的增广路且点i未被访问过
                    {
                        vis[i] = 1;
                        Q.push_back((i));//点i进入队列(即点i属于增广路上的一个点)
                        break;
                    }
                }
                if(i > n)//如果遍历所有点后在下一层没有找到增广路,就退出本层继续寻找下一条
                    Q.pop_back();//删除双端队列中最后一个元素
            }//找增广路
            else
            {
                int Minflow = INF, nv;
                int len = Q.size();//进入队列中点的个数
                for(int i = 1 ; i < len ; i++)
                {
                    int x = Q[i - 1];//前一个点
                    int y = Q[i];//后一个点
                    if(Minflow > G[x][y])
                    {
                        Minflow = G[x][y];
                        nv = x;//nv记录前端点
                    }//查找最小值即增光流量
                }
                Maxflow += Minflow;
                for(int i = 1 ; i < len ; i++) //更新流量
                {
                    int x = Q[i - 1];
                    int y = Q[i];
                    G[x][y] -= Minflow;//更新正向
                    G[y][x] += Minflow;//反向增加
                }
                while(!Q.empty() && Q.back() != nv)
                    Q.pop_back();//出队
            }
        }
    }
    return Maxflow;
}

int main()
{
    int a, b, c, m;
    while(~scanf("%d%d", &m, &n))
    {
        memset(G, 0, sizeof(G));
        while(m--)
        {
            scanf("%d%d%d", &a, &b, &c);
            G[a][b] += c;//处理重边
        }
        printf("%d\n", Dinic());
    }
    return 0;
}
/*
10 8
1 2 10
1 3 10
2 4 20
2 5 20
3 6 20
3 7 20
4 8 30
5 8 30
6 8 30
7 8 30
*/
View Code

 邻接表+Dinic(仅供参考)

#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#define INF 0x3f3f3f3f
#define N 1010
using namespace std;

struct Edge
{
    int u, v, next, flow;
} edge[N * N];

int layer[N], head[N], cnt;

void Init()
{
    memset(head, -1, sizeof(head));
    cnt = 0;
}

void AddEdge(int u, int v, int flow)
{
    edge[cnt].u = u;
    edge[cnt].v = v;
    edge[cnt].flow = flow;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}

bool BFS(int Start, int End)//分层
{
    queue<int>Q;
    memset(layer, -1, sizeof(layer));
    Q.push(Start);
    layer[Start] = 1;
    while(!Q.empty())
    {
        int u = Q.front();
        Q.pop();
        if(u == End)
            return true;
        for(int i = head[u] ; i != -1 ; i = edge[i].next)
        {
            int v = edge[i].v;
            if(layer[v] == -1 && edge[i].flow > 0)
            {
                layer[v] = layer[u] + 1;
                Q.push(v);
            }
        }
    }
    return false;
}

int DFS(int u, int Maxflow , int End)
{
    if(u == End)
        return Maxflow;
    int uflow = 0;
    for(int i = head[u] ; i != -1 ; i = edge[i].next)
    {
        int v = edge[i].v;
        if(layer[v] == layer[u] + 1 && edge[i].flow > 0)
        {
            int flow = min(edge[i].flow, Maxflow - uflow);
            flow = DFS(v, flow, End);
            edge[i].flow -= flow;
            edge[i^1].flow += flow;
            uflow += flow;

            if(uflow == Maxflow)
                break;
        }
    }
    if(uflow == 0)
        layer[u] = 0;
    return uflow;
}

int Dinic(int Start, int End)
{
    int Maxflow = 0;
    while(BFS(Start, End))
        Maxflow += DFS(Start, INF, End);
    return Maxflow;
}

int main()
{
    int m, n;
    while(~scanf("%d%d", &m, &n))
    {
        Init();
        int u, v, flow;
        while(m--)
        {
            scanf("%d%d%d", &u, &v, &flow);
            AddEdge(u, v, flow);
            AddEdge(v, u, 0);
        }
        printf("%d\n", Dinic(1, n));
    }
    return 0;
}
View Code

 

posted @ 2015-08-13 10:55  午夜阳光~  阅读(164)  评论(0编辑  收藏  举报