题目大意:每当下雨,农夫FJ最喜爱的养尊处优的地方周围就变成了一个池塘,这让他很不爽,所以决心要把这个问题解决掉,所以他就在四周建造了一些渠沟以便排水,更为巧妙地是可以把这水排到一个小溪处。编号为1的节点作为池塘,编号为n的地方作为小溪。求最大排水量
思路:赤裸裸的最大流。SPA+GAP再次撸过~~~要注意的是可能最大流会超int。还有的是:如果是拿邻接矩阵做的话要考虑重边问题(包含自环),但是邻接表的话什么鬼都不怕~~其实图论的特殊情况就是:重边(就是所谓的平行边,注意了最大流题目的平行边不能随便选择一条)、自环、负环、正环,以这些来设计数据的话,数据则会更有代表性~~嘻嘻
AC program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
using namespace std;
#define inf 1000000000
#define maxn 201
#define maxm 40001//62500
int num;
int n,m;
struct node
{
int next,to;
__int64 c;//note!!!
}e[maxm];
int box[maxn];//链式前向星
void init1()
{
num=0;
memset(box,-1,sizeof(box));
int u,v,w;
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
e[num].to=v;
e[num].c=w;
e[num].next=box[u];
box[u]=num;
num++;
///----
e[num].to=u;
e[num].c=0;
e[num].next=box[v];
box[v]=num;
num++;
///----
}
}
__int64 sap(int start,int end,int nnn)//note!!!返回值
{
int numh[maxn],h[maxn],cur[maxn],pre[maxn];
__int64 cur_flow,flow_ans=0;//note!!!
int u,tmp,neck,i;
memset(h,0,sizeof(h));
memset(numh,0,sizeof(numh));
memset(pre,-1,sizeof(pre));
for(int i=1;i<=nnn;i++)
cur[i]=box[i];
numh[0]=nnn;
u=start;
while(h[start]<nnn)
{
if(u==end)
{
cur_flow=inf;//note!!!
for(i=start;i!=end;i=e[cur[i]].to)
{
if(cur_flow>e[cur[i]].c)
{
neck=i;
cur_flow=e[cur[i]].c;
}
}
for(i=start;i!=end;i=e[cur[i]].to)
{
tmp=cur[i];
e[tmp].c-=cur_flow;
e[tmp^1].c+=cur_flow;
}
flow_ans+=cur_flow;
u=neck;
}
for(i=cur[u];i!=-1;i=e[i].next)
if(e[i].c&&h[u]==h[e[i].to]+1)
break;
if(i!=-1)
{
cur[u]=i;
pre[e[i].to]=u;
u=e[i].to;
}
else
{
if(0==--numh[h[u]])break;
cur[u]=box[u];
for(tmp=nnn,i=box[u];i!=-1;i=e[i].next)
if(e[i].c)
tmp=min(tmp,h[e[i].to]);
h[u]=tmp+1;
++numh[h[u]];
if(u!=start)u=pre[u];
}
}
return flow_ans;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
init1();
__int64 love;
love=sap(1,n,n);//n个点
printf("%I64d\n",love); //note!!!还有输出限制
}
//system("pause");
return 0;}

探讨使用最大流算法解决农夫FJ面临雨水积聚问题的方法,通过构建图模型并利用SPA+GAP算法计算最大排水量。

被折叠的 条评论
为什么被折叠?



