标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 19711 | Accepted: 9035 |
Description
Input
Output
Sample Input
3 3 3 1 10 2 1 2 2 2 1 3 3 1 2 6
Sample Output
7
分析
主要是建图,增加一个源点和汇点,将源点和第一个有这个猪圈钥匙的顾客连起来,边权就是这个猪圈猪的数量,如果源点和某个节点有重边的话,合并就是了
之后的顾客对于已经开了的猪圈,将上一个顾客和他相连,边权是正无穷,可以用一个last数组来记录上一个买这个猪圈的顾客
每个顾客和汇点相连,边权是他想买猪的数量。
#include<stdio.h> #include<string.h> #include<iostream> #include<queue> using namespace std; //**************************************************** //最大流模板Edmonds_Karp算法 //初始化:G[][],st,ed //****************************************************** const int MAXN = 200+10; const int INF = 0x3fffffff; int G[MAXN][MAXN];//存边的容量,没有边的初始化为0 int path[MAXN],flow[MAXN],st,ed; int n;//点的个数,编号0~n,n包括了源点和汇点 queue<int>q; int bfs() { int i,t; while(!q.empty()) q.pop();//清空队列 memset(path,-1,sizeof(path));//每次搜索前都把路径初始化成-1 path[st]=0; flow[st]=INF;//源点可以有无穷的流流进 q.push(st); while(!q.empty()){ t=q.front(); q.pop(); if(t==ed) break; for(i=0;i<=n;i++){ if(i!=st&&path[i]==-1&&G[t][i]){ flow[i]=flow[t]<G[t][i]?flow[t]:G[t][i]; q.push(i); path[i]=t; } } } if(path[ed]==-1) return -1;//即找不到汇点上去了。找不到增广路径了 return flow[ed]; } int Edmonds_Karp() { int max_flow=0; int step,now,pre; while((step=bfs())!=-1){ max_flow+=step; now=ed; while(now!=st){ pre=path[now]; G[pre][now]-=step; G[now][pre]+=step; now=pre; } } return max_flow; } int val[1100]; int last[1100]; int main() { int N,M; scanf("%d%d",&M,&N); st=0,ed=N+1,n=N+1; memset(val,0,sizeof(val)); memset(last,0,sizeof(last)); for(int i=1;i<=M;i++) scanf("%d",&val[i]); for(int i=1;i<=N;i++){ int A,B,v; scanf("%d",&A); for(int j=1;j<=A;j++){ scanf("%d",&v); if(last[v]==0){ G[st][i]+=val[v]; last[v]=i; } else{ G[last[v]][i]=INF; last[v]=i; } } scanf("%d",&B); G[i][ed]=B; } printf("%d\n",Edmonds_Karp()); return 0; }
标签:
原文地址:http://www.cnblogs.com/wangdongkai/p/5616618.html