poj 1149 pigs(最大流)

题目大意:迈克在农场工作,农场有 m 个猪舍,每个猪舍有若干只猪,但是迈克不能打开任何一间猪舍。有 n 个顾客前来购买,每个顾客有最大的购买数量,每个顾客可以购买某些猪舍的猪,且顾客可以打开这些猪舍,从中挑选猪仔。重要的是,迈克可以在打开的这些猪舍中重新分配猪仔。由于知道每个猪舍的猪仔数目和顾客的购买情况,求迈克可以卖出的最大数目的猪仔。

解题思路:将每个顾客看成一个点,加上源点、汇点。将每个猪舍的第一位客人与源点相连,容量为猪舍中猪仔的数目,将每个猪圈的前以为顾客与后一位顾客相连,容量为INF,将每位顾客与汇点相连,容量为顾客的最大购买量。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
int m,n,f,tag[1001];
queue<int> Q;
struct edge{
	int from;
	int to;
	int flow;
	int cap;
};
vector<edge>e;
vector<int>adj[1200];

void init(){
	f = 0;
	for(int i=0;i<=n+m+1;i++)
	    adj[i].clear();
}

void addedge(int from,int to,int flow,int cap){
	e.push_back((edge){from,to,flow,cap});
	e.push_back((edge){to,from,flow,0});
	int t = e.size();
	adj[from].push_back(t - 2);
	adj[to].push_back(t - 1);
}

void solve(){
	int i,j,a[1200],p[1200];
	for( ; ; ){
		memset(a,0,sizeof(a));
		a[0] = 10000000;
		while(!Q.empty())
		    Q.pop();
		Q.push(0);
		while(!Q.empty()){
			int x = Q.front();
			Q.pop();
			for(i=0;i<adj[x].size();i++){
				int t = adj[x][i] ;
				int v = e[t].to;
				if(!a[v] && e[t].flow < e[t].cap){
					a[v] = a[x] < e[t].cap - e[t].flow ? a[x] : e[t].cap - e[t].flow;
					Q.push(v);
					p[v] = t ;
				}
			}
		}
		
		if(!a[n+1])
		    break;
		int u = n+1;
		for( ; u != 0; u = e[p[u]].from){
			e[p[u]].flow += a[n+1] ;
			e[p[u] ^ 1].flow -= a[n+1] ;
		}
		f += a[n+1] ;
	}
}

int main(){
	int i,j,a,b;
	int p[1001],c[1001],x;
	while(scanf("%d%d",&m,&n) == 2){
		init();
		for(i=1;i<=m;i++)
		    cin >> c[i] ;
		memset(tag,0,sizeof(tag));
		for(i=1;i<=n;i++){
			cin >> a ;
			for(j=1;j<=a;j++){
				cin >> x ;
				if(!tag[x]){
				    addedge(0,i,0,c[x]);
					tag[x] = i ;
				}
				else
				    addedge(tag[x],i,0,100000);
			}
			cin >> b ;
			addedge(i,n+1,0,b);
		} 
		
		solve();
		
		printf("%d
",f);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/jxgapyw/p/4860547.html