题意:养猪场有M个猪圈,每个猪圈可以容纳的猪的数量没有限制.养猪场的工人没有钥匙,但是要买猪的客户有若干个猪圈的钥匙.当一个客户来买猪的时候他会把所有可以打开的猪圈打开,客户离开后工人可以将猪圈里剩余的猪分配到任意猪圈.工人预先知道客户的需求和所拥有的钥匙.问养猪场一天最多可以卖出多少头猪.
网络流的题目建图果然恶心….
建图:建立一个源点和一个汇点,如果一个客户i首先打开一个猪圈,将i与源点相连,容量为该猪圈的猪的数量;i后面紧接着有下一个客户j打开同一个猪圈的话,将i与j相连,容量为inf.每一个客户都与汇点相连,容量为该客户的需求.
建好图,直接用Dinic跑一遍就A了.刚看完Dinic算法,印象还是挺深的,没看模板写出来了.
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <queue>
#define MAX 1500
#define inf 10000000
using namespace std;
int level[MAX];//层次网络
int Map[MAX][MAX];//容量网络
bool vis[MAX];//判断猪圈是否被打开过
int N,M;
void Build_Map()
{
int i,j,k,B;
int Pnum[MAX];
memset(vis,0,sizeof(vis));
memset(Map,0,sizeof(Map));
scanf("%d%d",&M,&N);
for(i=1;i<=M;i++)
{
scanf("%d",&Pnum[i]);
}
for(i=1;i<=N;i++)
{
scanf("%d",&k);
for(j=0;j<k;j++)
{
scanf("%d",&B);
if(!vis[B])
{
Map[0][i]+=Pnum[B];
Pnum[B]=i;
vis[B]=1;
}else
{
Map[Pnum[B]][i]=inf;
}
}
scanf("%d",&B);
Map[i][N+1]=B;
}
}
bool BFS()
{
queue<int> q;
memset(level,0,sizeof(level));
level[0]=1;
q.push(0);
while(!q.empty())
{
int v=q.front();
q.pop();
for(int i=0;i<=N+1;i++)
{
if(Map[v][i]&&!level[i])
{
level[i]=level[v]+1;
q.push(i);
}
}
}
if(!level[N+1]) return false;
else return true;
}
int DFS(int v,int sum)
{
if(v==N+1) return sum;
int s=sum;
for(int i=0;sum&&i<=N+1;i++)
{
if(Map[v][i]&&level[v]+1==level[i])
{
int t=DFS(i,min(sum,Map[v][i]));
Map[v][i]-=t;
Map[i][v]+=t;
sum-=t;
}
}
return s-sum;
}
int main()
{
Build_Map();
int ans=0;
while(BFS())
ans+=DFS(0,inf);
printf("%d\n",ans);
return 0;
}