这个题的建图比较有难度也比较神奇 以每个买主为中心抽象为一层 而这每一层又包含了其他所有猪圈与该买主的关系
具体请点击这篇博客 有图看 很直观
#include <stdio.h>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1e9
struct node
{
int v;
int w;
int next;
};
node edge[10010];
int e[110][1010];
int pig[1010],need[110];
int first[110],dis[110],gap[110],cur[110],pre[110];
int n,m,num,ss,ee,ans;
void addedge(int u,int v,int w);
void init();
void build();
void isap();
void bfs();
int main()
{
int tar[1010];
int t,i,j,amt;
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
build();
isap();
printf("%d\n",ans);
}
return 0;
}
void addedge(int u,int v,int w)
{
edge[num].v=v;
edge[num].w=w;
edge[num].next=first[u];
first[u]=num++;
return;
}
void init()
{
int i,j,t1,t2;
memset(e,0,sizeof(e));
for(i=1;i<=m;i++)
{
scanf("%d",&pig[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&t1);
for(j=1;j<=t1;j++)
{
scanf("%d",&t2);
e[i][t2]=1;
}
scanf("%d",&need[i]);
}
return;
}
void build()
{
int tem[110],book[1010];
int i,j,t;
memset(tem,0,sizeof(tem));
memset(book,0,sizeof(book));
memset(first,-1,sizeof(first));
ss=n+1,ee=n+2,num=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(e[i][j]==1&&book[j]==0)
{
tem[i]+=pig[j];
book[j]=1;
}
}
}
for(i=1;i<=n;i++)
{
if(tem[i]>0)
{
addedge(ss,i,tem[i]);
addedge(i,ss,0);
}
addedge(i,ee,need[i]);
addedge(ee,i,0);
}
for(j=1;j<=m;j++)
{
t=-1;
for(i=1;i<=n;i++)
{
if(e[i][j]==1)
{
if(t!=-1)
{
addedge(t,i,N);
addedge(i,t,0);
}
t=i;
}
}
}
num=n+2;
return;
}
void isap()
{
int j,u,v,w,flow,minn;
bfs();
memcpy(cur,first,sizeof(first));
memset(pre,-1,sizeof(pre));
ans=0,u=ss,flow=N;
while(dis[ss]<num)
{
int &i=cur[u];
for(;i!=-1;i=edge[i].next)
{
v=edge[i].v,w=edge[i].w;
if(w>0&&dis[v]+1==dis[u])
{
pre[v]=i;
u=v,flow=min(flow,w);
if(u==ee)
{
while(u!=ss)
{
edge[pre[u]].w-=flow;
edge[pre[u]^1].w+=flow;
u=edge[pre[u]^1].v;
}
ans+=flow,flow=N;
}
break;
}
}
if(i==-1)
{
if(--gap[dis[u]]==0) break;
cur[u]=first[u];
minn=num-1;
for(j=first[u];j!=-1;j=edge[j].next)
{
v=edge[j].v,w=edge[j].w;
if(w>0)
{
minn=min(minn,dis[v]);
}
}
dis[u]=minn+1;
gap[dis[u]]++;
if(u!=ss)
{
u=edge[pre[u]^1].v;
}
}
}
return;
}
void bfs()
{
queue <int> que;
int i,u,v;
memset(dis,-1,sizeof(dis));
memset(gap,0,sizeof(gap));
que.push(ee);
dis[ee]=0;
while(!que.empty())
{
u=que.front();
que.pop();
gap[dis[u]]++;
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(dis[v]==-1)
{
que.push(v);
dis[v]=dis[u]+1;
}
}
}
return;
}