标签:
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 18255 | Accepted: 8300 |
Description
Input
Output
Sample Input
3 3 3 1 10 2 1 2 2 2 1 3 3 1 2 6
Sample Output
7题意:养猪场有m个猪圈,麦克没有猪圈钥匙,所以他不能打开猪圈。买猪的顾客有一些猪圈的钥匙,他们来买猪时,会将他们所拥有钥匙的猪圈全部打开,这样麦克就能重新分配每个猪圈的猪数量,当顾客走的时候,就再次把所有门都锁上,每个猪圈容纳猪的数量都是没有限制的。现在知道所有顾客拥有钥匙的情况以及他们要买的猪的数量,需要怎么安排,才能使得销售数量最大。输入告诉每个猪圈起始猪数量,以及每个顾客拥有的钥匙编号和要买猪的数量。
分析:一个网络流的题目。关键在于构造一个容量网络。《图论算法理论、实现及应用》这本书上有很详细的网络流知识讲解。
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define N 1009
#define INF 999999999
using namespace std;
int pre[N];
int cus[N][N];
int flow[N][N];
int pig[N];
int last[N];
int q[N*2];
int n,m;
int num,k;
int main()
{
int m,n;
while(~scanf("%d%d",&m,&n))
{
for(int i=1;i<=m;i++)
scanf("%d",&pig[i]);
memset(last,0,sizeof last);
memset(cus,0,sizeof cus);
int s=0,t=n+1;
for(int i=1;i<=n;i++)
{
scanf("%d",&num);
for(int j=0;j<num;j++)
{
scanf("%d",&k);
if(last[k]==0)
cus[s][i]+=pig[k];
else
cus[last[k]][i]=INF;//表示先last[k]拿过k猪圈的猪后i在拿
last[k]=i;
}
scanf("%d",&cus[i][t]);
}
for(int i=0;i<=n+2;i++)
for(int j=0;j<=n+2;j++)
flow[i][j]=0;
while(1)//多次BFS进行增广
{
int mmin=INF;
for(int i=0;i<=n+2;i++)
pre[i]=-2;
int qs=0,qe=1;
pre[0]=-1;q[qs]=0;//从源点开始
while(pre[t]==-2 && qs<qe)//找到一条增广路就更新一下
{
int v=q[qs++];
for(int i=1;i<=t;i++)
{
int p=cus[v][i]-flow[v][i];
if(pre[i]==-2 && p)
{
pre[i]=v;
q[qe++]=i;
mmin=min(mmin,p); //记录每次可增广的最小值
}
}
}
if(pre[t]==-2) break;
for(int i=pre[t],j=t; i!=-1; j=i,i=pre[i])
{
flow[i][j]+=mmin;
flow[j][i]=-flow[i][j];
}
}
int ans=0;
for(int i=1;i<t;i++)
ans+=flow[i][t];
printf("%d\n",ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/wust_zjx/article/details/47700649