[Poj1149]Pigs(最大流)

Description

一个工人在养猪场卖猪,现在有m个猪圈和n个顾客,每个猪圈的容量没有限制,每个顾客来之后会打开指定的猪圈,然后买猪,然后关闭所有他打开的猪圈,顾客总是一个接一个的来,当猪圈打开的时候,工人可以随意挪动打开的猪圈中的猪(只能在打开的猪圈中相互移动)问工人一天最多卖出去多少猪

Solution

建一下图跑一下最大流就行,怎么建图以后再说

Code

#include <cstdio>
#include <algorithm>
#define N 110
#define Inf 0x7fffffff
using namespace std;

struct info{int to,nex,f;}e[N*1000];
int n,m,T,S,tot,nodes,head[N],Ans,cnt[N],dis[N],c[N*10],fst[N*10];

inline void Link(int u,int v,int f){
	e[++tot].to=v;e[tot].nex=head[u];head[u]=tot;e[tot].f=f;
	e[++tot].to=u;e[tot].nex=head[v];head[v]=tot;e[tot].f=0;
}

inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

inline void Init(){
	m=read(),n=read();
	S=0,tot=1,nodes=(T=n+1)+1;
	for(int i=1;i<=m;++i) c[i]=read();
	for(int i=1;i<=n;++i){
		int k=read();
		for(int j=1;j<=k;++j){
			int tmp=read();
			if(fst[tmp]) Link(fst[tmp],i,Inf);
			else Link(S,i,c[tmp]);
			fst[tmp]=i; 
		}
		int v=read();
		Link(i,T,v);
	}
}

int sap(int u,int d){
	if(u==T) return d;
	int sum=0,mins=nodes;
	for(int i=head[u];i;i=e[i].nex){
		int v=e[i].to;
		if(e[i].f>0&&dis[u]==dis[v]+1){
			int save=sap(v,min(d-sum,e[i].f));
			sum+=save;
			e[i].f-=save;
			e[i^1].f+=save;
			if(dis[S]>=nodes||sum==d) return sum;
		}
		if(e[i].f>0) mins=min(mins,dis[v]);
	}
	if(!sum){
		if(!(--cnt[dis[u]])) dis[S]=nodes;
		else ++cnt[dis[u]=mins+1];
	}
	return sum;
}

void SAP(){cnt[0]=nodes;while(dis[S]<nodes) Ans+=sap(S,Inf);}

int main(){
	Init();
	SAP();
	printf("%d\n",Ans);
	return 0;
}

posted @ 2018-02-23 19:40  void_f  阅读(146)  评论(0编辑  收藏  举报