1169: Super Market 网络流 EK

 1169: Super Market


ResultTIME LimitMEMORY LimitRun TimesAC TimesJUDGE
3s8192K478133Standard

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;
}        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值