暑假培训,前几天没老师讲,自己在机房看资料,偶然发现网络流的算法,看来两天,不知所云,说的云里雾里的。
网上找资料,大多用C++写的,后来发现一大牛的代码。看来半天,豁然开朗,大牛就是大牛。代码相当规范、简练。唉。。。。
题目链接:http://poj.org/problem?id=1273
Drainage Ditches
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 55336 | Accepted: 21139 |
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.
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
题目大意:下雨的时候约翰的田里总是积水,积水把他种的三叶草给淹了,他于是做了若干排水沟,每条沟在起始处安置一个阀门来控制这条沟的最大排水量,现在给出沟的条数以及阀门的个数。并给出每条沟的最大排水量。约翰的田里的积水处是阀门1,排出水的位置是最后一个阀门。求约翰在处理积水时的最大排出量。
代码运行情况:如图(第一次写博客,图在下面,将就着看吧)
图片不知怎么的传不上来,写在这吧 : Accept 628k 0(16)MS C 1869B 第一次提交0ms 之后一直16ms
参考的资料:http://pan.baidu.com/s/1nt5bngX
代码:
#include <stdio.h>
#include <string.h>
struct Map
{
int f;//反向
int c;//正向
}map[250][250];//储存图
int pre[250]; //储存前驱点
int q[250*250]; //广度搜索用的队列
int v[250]; //记录点对应的流量
int N,M,s,t;
int Abs(int x)//求绝对值 貌似写成abs编译不过
{
return x>0?x:-x;
}
int min(int x,int y)//求最小值
{
return x<y?x:y;
}
void set()//初始化 输入
{
int i,a,b,c;
memset(map,0,sizeof(map));
for(i=0;i<N;i++)
{
scanf("%d%d%d",&a,&b,&c);
map[a][b].c+=c;
}
}
void solve()
{
int i,j;
int head,tail,ans;//队列的头尾指针
s=1;
t=M;
while(1) //寻找 所有从源点到汇点的路径
{
memset(pre,0,sizeof(pre));
head=0,tail=1;
q[0]=s; //源点入队
v[s]=1000000000;//源点可供应的流量假定无限大 (给定一个足够大的值)
pre[s]=s;//源点的前驱为其本身
while(head<tail&&pre[t]==0)
/*寻找单条从源点到汇点的路径(队首小于队尾 队列未访问到底 pre[t]==0汇点前驱为0 即汇点未被访问到)*/
{
i=q[head]; //i为当前已发现的点
for(j=1;j<=M;j++)//添加所有与head点相连的点 到队列
{
if(!pre[j]) //当前点没被利用
{
if(map[i][j].f<map[i][j].c)//当前路径还能提供流量 map[i][j].f==map[i][j].c==0 此路不通
{
pre[j]=i;//记录当前点的前驱
q[tail++]=j;//入队
v[j]=min(v[i],map[i][j].c-map[i][j].f);//比较 记录最大流
}
else if(map[j][i].f>0)
{
pre[j]=-i;
q[tail++]=j;
v[j]=min(v[i],map[j][i].f);
}
}
}
head++;//出队 其实我一直感觉 写成循环队列会好些
}
if(pre[t]==0)break;//没有前驱点 即没找到 所有的可行路径均已被发现
i=t;
while(i!=s)//回朔 计算该路的流量 添加反向路径 并修改流量
{
j=Abs(pre[i]);
if(pre[i]>0)map[j][i].f+=v[t];//此为正向
else map[i][j].f-=v[t];//反向路径
i=j;
}
}
ans=0;
for(i=1;i<=M;i++)ans+=map[s][i].f;//计算总流量
printf("%d\n",ans);
}
int main()
{
while(~scanf("%d%d",&N,&M))
{
set();
solve();
}
return 0;
}