您的位置:首页 > 大数据 > 人工智能

POJ1273 Drainage Ditches【最大流】【SAP】

2015-04-09 19:46 351 查看
题目链接:

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

题目大意:

农民John的田里有M个池塘和N条水沟用来排水,池塘编号为1~M,1号池塘是所有水沟的源点,

M号池塘是水沟的汇点。给你N条水沟所连接的池塘和所能流过的水量,求整个水沟从源点到汇点

最多能流多少水。

思路:

很明显的求网络流最大流问题。用链式前向星(邻接表)来存储网络,这样就不用考虑重边问题了。这

里的重边其实就是平行边。用SAP算法+GAP优化来求最大流就可以了。SAP+GAP模板参考我的另

一篇博文:http://blog.csdn.net/lianai911/article/details/44962653

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN = 220;
const int MAXM = MAXN*MAXN;
const int INF = 0xffffff0;

struct EdgeNode
{
int to;
int w;
int next;
}Edges[MAXM];
int Head[MAXN],id;

void AddEdges(int u,int v,int w)
{
Edges[id].to = v;
Edges[id].w = w;
Edges[id].next = Head[u];
Head[u] = id++;
Edges[id].to = u;
Edges[id].w = 0;
Edges[id].next = Head[v];
Head[v] = id++;
}

int Numh[MAXN],h[MAXN],curedges[MAXN],pre[MAXN];

void BFS(int end,int N)
{
memset(Numh,0,sizeof(Numh));
for(int i = 1; i <= N; ++i)
Numh[h[i]=N]++;
h[end] = 0;
Numh
--;
Numh[0]++;
queue<int> Q;
Q.push(end);

while(!Q.empty())
{
int v = Q.front();
Q.pop();
int i = Head[v];
while(i != -1)
{
int u = Edges[i].to;

if(h[u] < N)
{
i = Edges[i].next;
continue;
}

h[u] = h[v] + 1;
Numh
--;
Numh[h[u]]++;
Q.push(u);
i = Edges[i].next;
}
}
}

int SAP(int start,int end,int N)
{
int Curflow,FlowAns = 0,temp,neck;
memset(h,0,sizeof(h));
memset(pre,-1,sizeof(pre));
for(int i = 1; i <= N; ++i)
curedges[i] = Head[i];

BFS(end,N);
int u = start;
while(h[start] < N)
{
if(u == end)
{
Curflow = INF;
for(int i = start; i != end; i = Edges[curedges[i]].to)
{
if(Curflow > Edges[curedges[i]].w)
{
neck = i;
Curflow = Edges[curedges[i]].w;
}
}
for(int i = start; i != end; i = Edges[curedges[i]].to)
{
temp = curedges[i];
Edges[temp].w -= Curflow;
Edges[temp^1].w += Curflow;
}
FlowAns += Curflow;
u = neck;
}
int i;
for(i = curedges[u]; i != -1; i = Edges[i].next)
if(Edges[i].w && h[u]==h[Edges[i].to]+1)
break;
if(i != -1)
{
curedges[u] = i;
pre[Edges[i].to] = u;
u = Edges[i].to;
}
else
{
if(0 == --Numh[h[u]])
break;
curedges[u] = Head[u];
for(temp = N,i = Head[u]; i != -1; i = Edges[i].next)
if(Edges[i].w)
temp = min(temp,h[Edges[i].to]);
h[u] = temp + 1;
++Numh[h[u]];
if(u != start)
u = pre[u];
}
}
return FlowAns;
}

int main()
{
int N,M,u,v,w;
while(~scanf("%d%d",&N,&M))
{
memset(Head,-1,sizeof(Head));
id = 0;
for(int i = 0; i < N; ++i)
{
scanf("%d%d%d",&u,&v,&w);
AddEdges(u,v,w);
}
printf("%d\n",SAP(1,M,M));
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: