最大流:
题意:给你m个猪圈以及每个猪圈里原来有多少头猪,先后给你n个人,每个人能打开一些猪圈并且他们最多想买Ki头猪,在每一个人买完后能将打开的猪圈中的猪顺意分配在这次打开猪圈里,在下一个人来之前 已打开的猪圈被锁上。问这个人一天最多卖出多少猪。
建立超级源点和第一个打开某个猪圈的人相连,权值为它打开的猪圈的初始猪的头数,当一个人有多把钥匙时,权值可以合并。
接下来打开猪圈的人和第一个打开猪圈的人相连,权值为inf。
建立超级汇点和每一个人相连,权值为他能购买猪的上限。
建好图后,就是裸的最大流算法了,我用的EK。
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#define M 1100
#define inf 100000000
int map[M][M];
int pre[M],queue[M],pig[M],buy[M],vis[M];
int flow,start,end,tot,ans,owner[M];
using namespace std;
int bfs()
{
int p=0,q=1;
queue[0]=1;
flow=inf;
memset(pre,-1,sizeof(pre));
while(p<q)
{
int s=queue[++p];
for(int i=1;i<=end;i++)
{
if(pre[i]==-1&&map[s][i]>0)
{
pre[i]=s;
flow=min(flow,map[s][i]);
queue[++q]=i;
if(i==end) return flow;
}
}
}
return -1;
}
int Edmonds_Karp()
{
tot=0;
while((ans=bfs())!=-1)
{
tot+=ans;
int now=end;
while(now!=0)
{
map[pre[now]][now]-=ans;
map[now][pre[now]]+=ans;
now=pre[now];
}
}
return tot;
}
int main()
{
int n,m,i,j,num,temp;
while(scanf("%d%d",&m,&n)!=EOF)
{
for(i=1;i<=m;i++)
scanf("%d",&pig[i]);
memset(vis,0,sizeof(vis));
memset(map,0,sizeof(map));
for(j=1;j<=n;j++)
{
scanf("%d",&num);
while(num--)
{
scanf("%d",&temp);
if(vis[temp]==0)
map[0][j]+=pig[temp],vis[temp]=j;
else
map[vis[temp]][j]=inf;
}
scanf("%d",&temp);
map[j][n+1]=temp;
}
start=0,end=n+1;
printf("%d\n",Edmonds_Karp());
}
return 0;
}
poj 1149 PIGS
本文介绍了一种利用最大流算法解决特定问题的方法:即给定若干猪圈及其中的猪的数量,以及一系列顾客能打开某些猪圈并购买一定数量猪的情况,通过构建最大流图模型来确定一天内最多能卖出多少猪。文章详细描述了如何构造图模型,并使用 Edmonds-Karp 算法求解最大流。
摘要由CSDN通过智能技术生成