题意:n个人买猪,有m个猪圈,每个人可以买多个猪圈的k头猪,买完之后这些猪圈的猪就可以走动了,否则每一个猪圈的猪只能呆在各自的猪圈里。
问最多可以卖出几头猪。
思路:http://imlazy.ycool.com/post.2059102.html
第一道网络流,拿来验证yy的模版。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> using namespace std; const int M = 20009; const int N = 209; const int INF = 0x7ffffff; int g[N][N],gap[N],dist[N],pre[N],cur[N]; ///s源,t汇,所有点1-n int n,m,s,t; int calc(){ int maxflow=0,aug=INF,u,v; memset(gap,0,sizeof(gap)); memset(dist,0,sizeof(dist)); for(int i=0; i<=n; i++)cur[i]=1; u=pre[s]=s; gap[0]=n; while(dist[s]<=n){ loop: for(v=cur[u]; v<=n; v++) if(g[u][v]>0 &&dist[u]==dist[v]+1) { cur[u]=v; aug=min(aug,g[u][v]); pre[v]=u; u=v; if(v==t){ maxflow+=aug; for(u=pre[u];v!=s;v=u,u=pre[u]){ g[u][v]-=aug; g[v][u]+=aug; } aug=INF; } goto loop; } int mind=n; for(v=1; v<=n; v++) if(g[u][v]>0 &&mind>dist[v]){ mind=dist[v]; cur[u]=v; } if(--gap[dist[u]]<=0)break; gap[dist[u]=mind+1]++; u=pre[u]; } return maxflow; } int pig[N],re[N]; void init() { memset(re,0,sizeof(re)); memset(g,0,sizeof(g)); } int main() { freopen("in.txt","r",stdin); while(~scanf("%d%d",&m,&n)) { init(); n++; s=1,t=n+1; for(int i=1; i<=m; i++) scanf("%d",&pig[i]); for(int i=2; i<=n; i++) { int a,b; scanf("%d",&a); for(int j=0; j<a; j++) { scanf("%d",&b); if(re[b]==0) g[s][i]+=pig[b]; else g[re[b]][i]=INF; if(!re[b]) re[b]=i; } scanf("%d",&b); g[i][t]+=b; }n++; printf("%d\n",calc()); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> using namespace std; const int N = 209; const int M = 2009; const int INF = 0x3f3f3f3f; struct LT{ int f,t,nex,c; }L[M*4]; int F[N],cnt; void add(int f,int t,int c){ L[cnt].c = c;L[cnt].f = f; L[cnt].t = t;L[cnt].nex = F[f]; F[f] = cnt++; L[cnt].c = 0;L[cnt].f = t; L[cnt].t = f;L[cnt].nex = F[t]; F[t] = cnt++; } int dep[N],num[N],pre[N],cur[N],que[N]; ///s源 t汇 所有点1-n int s,t,n,p; void bfs(){ int front=0, rear=0; int x,i,v; for(i=1;i<=n;i++) dep[i]=INF; dep[t]=0; memset(num,0,sizeof(num)); num[dep[t]]++; que[rear++]=t; while(front<rear){ x=que[front++];//cout<<x<<endl; for(i=F[x]; i!=-1; i=L[i].nex){ v=L[i].t; if(dep[v]==INF &&L[i^1].c){ dep[v]=dep[x]+1; num[dep[v]]++; que[rear++]=v; } } } } int find(int x){ for(int i=F[x]; i!=-1; i=L[i].nex) if(L[i].c &&dep[L[i].t]+1==dep[x]){ cur[L[i].t]=i; return L[i].t; } return -1; } int relable(int i){ int min=INF; for(int j=F[i]; j!=-1; j=L[j].nex) if(L[j].c&&dep[L[j].t]+1<min){ min=dep[L[j].t]+1; } return min==INF?n:min; } int maxflow(){ bfs(); int flow=0,i=s,j,delta; memset(pre,-1,sizeof(pre)); while(dep[s]<n){ j=find(i); if(j>0){ pre[j]=i; i=j; if(i==t){ delta=INF; for(i=t; i!=s; i=pre[i]) if(L[cur[i]].c<delta) delta=L[cur[i]].c; for(i=t; i!=s; i=pre[i]){ L[cur[i]].c-=delta; L[cur[i]^1].c+=delta; } flow+=delta; } }else{ int x=relable(i); num[x]++; num[dep[i]]--; if(num[dep[i]]==0)return flow; dep[i]=x; if(i!=s)i=pre[i]; } } return flow; } int pig[N],re[N]; void init() { cnt = 0; memset(F,-1,sizeof(F)); memset(re,0,sizeof(re)); } int main() { freopen("in.txt","r",stdin); int m; while(~scanf("%d%d",&m,&n)) { init(); n++; s=1,t=n+1; for(int i=1; i<=m; i++) scanf("%d",&pig[i]); for(int i=2; i<=n; i++) { int a,b; scanf("%d",&a); for(int j=0; j<a; j++) { scanf("%d",&b); if(re[b]==0) add(s,i,pig[b]); else add(re[b],i,INF); if(!re[b]) re[b]=i; } scanf("%d",&b); add(i,t,b); }n++; printf("%d\n",maxflow()); } return 0; }