poj1149 2010.3.5

本博客探讨了最大流算法在解决Pigs问题上的应用,详细解释了如何通过建立图模型并运用Relabel-To-Front算法求解最大流问题,以最大化销售数量。通过实例说明了算法的具体步骤和实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

poj1149 2010.3.5

Poj 1149   Pigs

 

【关键字】

最大流

【摘要】

一些顾客要到好多个猪圈里去买猪,每个人有一些猪圈的钥匙,求最多可以卖出多少猪。

【正文】

1、题目描述

PIGS

Time Limit: 1000MS Memory Limit: 10000K

Total Submissions: 6439  Accepted: 2761

Description

Mirko works on a pig farm that consists ofM locked pig-houses and Mirko can't unlock any pighouse because he doesn't havethe keys. Customers come to the farm one after another. Each of them has keysto some pig-houses and wants to buy a certain number of pigs.

All data concerning customers planning tovisit the farm on that particular day are available to Mirko early in themorning so that he can make a sales-plan in order to maximize the number ofpigs sold.

More precisely, the procedure is asfollowing: the customer arives, opens all pig-houses to which he has the key,Mirko sells a certain number of pigs from all the unlocked pig-houses to him,and, if Mirko wants, he can redistribute the remaining pigs across the unlockedpig-houses.

An unlimited number of pigs can be placedin every pig-house.

Write a program that will find the maximumnumber of pigs that he can sell on that day.

Input

The first line of input contains twointegers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighousesand number of customers. Pig houses are numbered from 1 to M and customers arenumbered from 1 to N.

The next line contains M integeres, foreach pig-house initial number of pigs. The number of pigs in each pig-house isgreater or equal to 0 and less or equal to 1000.

The next N lines contains records about thecustomers in the following form ( record about the i-th customer is written inthe (i+2)-th line):

A K1 K2 ... KA B It means that thiscustomer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wantsto buy B pigs. Numbers A and B can be equal to 0.

Output

The first and only line of the outputshould contain the number of sold pigs.

SampleInput

3 3

3 1 10

2 1 2 2

2 1 3 3

1 2 6

SampleOutput

7

Source

Croatia OI 2002 Final Exam - First day

 

2、算法分析

圈为顶点。新设两个顶点,一个s,一个t,当第一个顾客有个一个猪圈的钥匙时,就有一条从s到该顾客的边,容量为猪圈中猪的数量,以后另外有顾客有这个猪圈的钥匙是,则有一条从前一个顾客到这个顾客的边,容量为无穷大,同时每个顾客都有到t的边,容量为顾客的需求量。求最大流,使用Relabel-To-Front算法,具体算法:最大流问题

调试问题:

忘记合并重边

感慨:

1.      图的问题,题目提供的数据,必然是一个用来当节点,一个用来建边的

2.      图的题目,图的建立很重要。

3、源码

#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

#define MAXN 1000+10
#define INF 1000000000

int flow[MAXN][MAXN],cap[MAXN][MAXN],a[MAXN],p[MAXN];
int n,s,t,m,f,nmax;
int flag[MAXN];
int pig[MAXN];

void edmondskarp();
void init();

void edmondskarp()
{
	queue<int> q;
	memset(flow,0,sizeof(flow));
	f=0;
	for(;;)
	{
		memset(a,0,sizeof(a));
		a[s]=INF;
		q.push(s);
		while (!q.empty())
		{
			int u=q.front();
			q.pop();
			for(int v=1;v<=n;v++)
				if (!a[v]&&cap[u][v]>flow[u][v])
				{
					p[v]=u;
					q.push(v);
					if (a[u]<cap[u][v]-flow[u][v])
						a[v]=a[u];
					else a[v]=cap[u][v]-flow[u][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];
	}
}

void init()
{
	int i,j,t1,t2;
	for(i=1;i<=m;i++)
		scanf("%d",&pig[i]);
	for(i=1;i<=n-2;i++)
	{
		scanf("%d",&t1);
		for(j=1;j<=t1;j++)
		{
			scanf("%d",&t2);
			if (flag[t2])
			{
				cap[flag[t2]][i]=INF;
				flag[t2]=i;
			}
			else
			{
				flag[t2]=i;
				cap[s][i]+=pig[t2];//少了这个加号,就回wa的很惨
			}
		}
		scanf("%d",&cap[i][t]);
	}	
}
int main()
{
	scanf("%d %d",&m,&n);
	memset(cap,0,sizeof(cap));
	memset(flag,0,sizeof(flag));
	n++;
	s=n;
	n++;
	t=n;
	init();
	edmondskarp();
	printf("%d\n",f);
		return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值