【poj1187】【最大流】PIGS

经典的最大流模型,按照下列规则建出网络图,然后做一次最大流即可。

• 每个顾客分别用一个结点来表示。
• 对于每个猪圈的第一个顾客,从源点向他连一条边,容量就是该猪圈里的猪的初始数量。如果从源点到一名顾客有多条边,则可以把它们合并成一条,容量相加。
• 对于每个猪圈,假设有 n 个顾客打开过它,则对所有整数 i∈[1, n),从该猪圈的第 i 个顾客向第 i + 1 个顾客连一条边,容量为∞。
• 从各个顾客到汇点各有一条边,容量是各个顾客能买的数量上限。

代码:

#include<cstdio>
#include<cstring>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 100 + 10;
const int maxm = 1000 + 10;
int cur[maxn],dis[maxn],gap[maxn],pre[maxn],flow[maxn];
int tmp[maxm],last[maxm];
int cap[maxn][maxn];
bool flag[maxm];
int n,m;
int s,t,nodenum;
void init()
{
	freopen("poj1149.in","r",stdin);
	freopen("poj1149.out","w",stdout);
}

inline int min(int a,int b)
{
	return a < b ? a : b;
}

void readdata()
{
	memset(flag,false,sizeof(flag));
	scanf("%d%d",&m,&n);
	nodenum = n + 2;
	s = 0;t = n + 1;
	for(int i = 1;i <= m;i++)
	{
		scanf("%d",&tmp[i]);
	}
	for(int i = 1;i <= n;i++)
	{
		int cnt;
		scanf("%d",&cnt);
		for(int j = 1;j <= cnt;j++)
		{
			int p;
			scanf("%d",&p);
			if(!flag[p])
			{
				flag[p] = true;
				cap[s][i] += tmp[p];
				last[p] = i;
			}
			else
			{	
				cap[last[p]][i] = inf;
				last[p] = i;
			}
		}
		int limit;
		scanf("%d",&limit);
		cap[i][n+1] = limit;
	}
}

int sap()
{
	memset(cur,0,sizeof(cur));
	memset(dis,0,sizeof(dis));
	memset(gap,0,sizeof(gap));
	int u = pre[s] = s,maxflow = 0,aug = inf;
	gap[0] = nodenum;
	while(dis[s] < nodenum)
	{
loop:	for(int v = cur[u];v < nodenum;v++)
		{
			if(cap[u][v] && dis[u] == dis[v] + 1)
			{
				cur[u] = v;
				aug = min(aug,cap[u][v]);
				pre[v] = u;
				u = v;
				if(v == t)
				{
					maxflow += aug;
					for(u = pre[u];v != s;v = u,u = pre[u])
					{
						cap[u][v] -= aug;
						cap[v][u] += aug;
					}
					aug = inf;
				}
				goto loop;
			}
		}
		int mind = n + 1;
		for(int v = 1;v < nodenum;v++)
		{
			if(cap[u][v] && (mind > dis[v]))
			{
				cur[u] = v;
				mind = dis[v];
			}
		}
		if((--gap[dis[u]]) == 0)break;
		gap[dis[u] = mind + 1]++;
		u = pre[u];
	}
	return maxflow;
}

void solve()
{
	printf("%d",sap());
}

int main()
{
	init();
	readdata();
	solve();
	return 0;
}




你可能感兴趣的:(【poj1187】【最大流】PIGS)