poj 1149

来源:互联网 发布:mac开机密码怎么设置 编辑:程序博客网 时间:2024/05/18 02:46

     又是一个网络流的构图题。不是那么容易就想得到的,尤其是没有接触到很多网络流题目时。构图时由于人的数目较少,因此就只用人做结点。对于每一个猪舍的钥匙,若是第一次出现,则源点与该人连接一条边,容量为该猪舍的初始猪的数目,否则,当前人与前一个有此钥匙的人连一条边,容量无穷大。最后每一个人和汇点连一条边,容量为是他想买的猪的数目,最后,求一次最大流即可。

 

这里有个很详细的解题报告:

 

http://imlazy.ycool.com/post.2059102.html

 

     以下是代码:

 

 

#include<cstdio>#include<cstring>using namespace std;const int M=10000;const int N=1200;const int INF=1<<29;struct node{int u,v,cap,flow;int next; }edge[2*M];int head[N],num;int store[N],vis[N];int level[N];int m,n,s1,t1;void init(){for(int i=0;i<=n+m+3;i++)head[i]=-1;num=0;s1=0;t1=n+m+1;}void addege(int u,int v,int cap){edge[num].u=u;edge[num].v=v;edge[num].cap=cap;edge[num].flow=0;edge[num].next=head[u];head[u]=num++;edge[num].u=v;edge[num].v=u;edge[num].cap=0;edge[num].flow=0;edge[num].next=head[v];head[v]=num++;}int dinic_dfs(int sta,int end,int ver){int stack[N*10],top=0;int flow=0,cur,ptr,pre[N],minf,i;int del[N];for(i=0;i<=ver;i++){del[i]=0;}stack[top++]=sta;pre[sta]=sta;cur=sta;while(top){while(cur!=end && top){for(i=head[cur];i!=-1;i=edge[i].next){int v=edge[i].v;if(level[v]==level[cur]+1 && edge[i].cap>edge[i].flow && !del[v]){stack[top++]=v;cur=v;pre[v]=i;break;}}if(i==-1){del[cur]=1;top--;if(top)cur=stack[top-1];}}if(cur==end){minf=INF;while(cur!=sta){cur=pre[cur];if(edge[cur].cap-edge[cur].flow<minf) minf=edge[cur].cap-edge[cur].flow;cur=edge[cur].u;}cur=end;while(cur!=sta){cur=pre[cur];edge[cur].flow+=minf;edge[cur^1].flow-=minf;if(edge[cur].cap-edge[cur].flow==0){ptr=edge[cur].u;}cur=edge[cur].u;}while(top>0 && stack[top-1]!=ptr) top--;if(top) cur=stack[top-1];flow+=minf;}}return flow;}bool dinic_bfs(int sta,int end,int ver){int i,j;int queue[10*N];for(i=0;i<=ver;i++){level[i]=-1;}int rear=0;queue[rear++]=sta;level[sta]=0;for(i=0;i<rear;i++){for(j=head[queue[i]];j!=-1;j=edge[j].next){int v=edge[j].v;if(level[v]==-1 && edge[j].cap>edge[j].flow){level[v]=level[queue[i]]+1;queue[rear++]=v;}}}return level[end]>=0;}int dinic(int sta,int end,int ver){int flow=0,t;while(dinic_bfs(sta,end,ver)){t=dinic_dfs(sta,end,ver);if(t) flow+=t;else break;}return flow;}int main(){ // freopen("in.txt","r",stdin);scanf("%d%d",&m,&n);init();int i,j;int a,b,c;memset(vis,0,sizeof(vis));for(i=1;i<=m;i++)scanf("%d",&store[i]);for(i=1;i<=n;i++){scanf("%d",&a);for(j=0;j<a;j++){scanf("%d",&b);if(!vis[b]){addege(s1,i,store[b]);}elseaddege(vis[b],i,INF);vis[b]=i;}scanf("%d",&c);addege(i,t1,c);}printf("%d/n",dinic(s1,t1,t1+1));return 0;}