1169: Super Market
| Result | TIME Limit | MEMORY Limit | Run Times | AC Times | JUDGE |
|---|---|---|---|---|---|
| 3s | 8192K | 478 | 133 | Standard |
1st Jilin University ACM International Collegiate Programming Contest
Mr. Steward is the CEO of ACM(Auction Collecting Market). We all know it is a super market where Mr. Steward stores various of interesting goods from which customers pick out their lovings by themselves. Of course, settle accounts at the cashier before they leave the super market. Mr. Steward is so smart a bussiness man so that his super market becomes more and more thriving and prosperous. So he decides to open a branch super market in the east of the city. But the main super market is located in the west of the city, and when the branch super market is short of some certain type of goods, Mr. Steward has to transport some of it from the main super market to the branch super market by trucks. There are N crosses between the main super market and the branch super market. Every pair of two crosses may be connected by zero or only one one-way street. The main super market is always located on cross 1 and the branch super market is always located on cross N. The number of goods mustn't exceed the limitation of the street where the goods are transported on. For example, look at the graph below:

In this example, there are 3 crosses. The limitation on the street between cross 1 and cross 2 is 4, that means Mr. Steward can never transport more than 4 goods from cross 1 to cross 2 at a time. Similarly, Mr. Steward can never transport more than 3 goods from cross 2 to cross 3 and never more than 5 goods from cross 1 to cross 3 at a time too. Now Mr. Steward needs to know what the maximum number of goods he can transport from the main super market to the branch super market at a time. In this example, it is 8.
Input Specification
The input consists of several test cases. Each test case is in the following format:
The first line of each test case is an integer N(1<=N<=30).
The next N lines each contains N non-negative integers. The jth integer of the (i+1)th line of each test case designating the limitation on the street from cross i to cross j.
The last test case is marked by N=0, which should not be proceeded.
Output Specification
For each test case, your program should print a single line which looks like 'Maximum number of goods: max.', where max is what your program computes.
Sample Input
3 0 4 5 0 0 3 0 0 0 5 0 10 0 40 0 0 0 20 0 0 0 0 0 0 30 0 0 0 0 50 0 0 0 0 0 0
Sample Output
Maximum number of goods: 8. Maximum number of goods: 50.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int point_num=300;
int cap[point_num][point_num],flow[point_num][point_num];//cap表示最大容量
int a[point_num]; //表示从s到节点i的路径上的最小残量a[i],则a[t]就是整条s-t道路上的最小残量。
//由于a[i]总是正数,则用它代替了vis[]标记数组
int p[point_num];//记录父亲节点
int s,t,n;//源,汇 ,点个数
const int inf=(1<<31)-1;
int maxflow()//Edmonds-Karp
{
s=0,t=n-1;//这道题源和汇是第一个点和最后一个点
queue<int> q;
memset(flow,0,sizeof(flow));
int f=0;//s-t的总流量
for(;;)
{
memset(a,0,sizeof(a));
a[s]=inf;
q.push(s);
while(!q.empty())//bfs找增广路
{
int u=q.front();q.pop();
for(int v=0;v<n;v++)
{
if(a[v]==0&&cap[u][v]>flow[u][v])//找到新节点
{
p[v]=u;q.push(v);//记录v的父亲,并加入队列中
a[v]=a[u]<cap[u][v]-flow[u][v]?a[u]:cap[u][v]-flow[u][v];//s-v路径上的最小残量
}
}
}
if(a[t]==0) break;//找不到,则当前流已经是最大流了
for(int u=t;u!=s;u=p[u])//从汇点往回走
{
flow[p[u]][u]+=a[t]; //更新正向流量
flow[u][p[u]]-=a[t];//更新反向流量
}
f+=a[t];//更新从s流出的总流量
}
return f;
}
int main()
{
while(cin>>n&&n)
{
for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>cap[i][j];
int ans=maxflow();
cout<<"Maximum number of goods: "<<ans<<"."<<endl;
}
return 0;
}

本文介绍了一种基于Edmonds-Karp算法解决超市间货物运输的最大流问题。通过构建图模型,利用广度优先搜索寻找增广路径,不断更新流量直至无法再增加,最终求得从主超市到分支超市的最大货物运输量。

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



