首页 > 代码库 > POJ 1149 PIGS 最大流
POJ 1149 PIGS 最大流
第一次做网络流,看着教材里面的题解做的= =
用的是Ford,应该是最好理解的把,就是不断的找有没有从源点到汇点的增广路然后更新。
建图真是难啊,而且感觉细节要注意的地方比较多,一开始没有考虑反向弧,WA了两发,sad...
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <climits>#include <string>#include <iostream>#include <map>#include <cstdlib>#include <list>#include <set>#include <queue>#include <stack>using namespace std;typedef long long LL;const int INF = INT_MAX / 4;const int maxn = 305;const int maxm = 3005;int n,m,s,t;int A[maxn],K[maxn][maxm],B[maxn]; //A为每个顾客有的钥匙数量,K为钥匙的类型,B为顾客的需求int P[maxm],firstp[maxm]; //猪圈中猪的数量,每个猪圈的第一个客户int dist[maxn][maxn];void input() { for(int i = 1;i <= m;i++) { scanf("%d",&P[i]); } for(int i = 1;i <= n;i++) { scanf("%d",&A[i]); for(int j = 1;j <= A[i];j++) { scanf("%d",&K[i][j]); } scanf("%d",&B[i]); }}void init() { s = 0; t = n + 1; memset(firstp,0,sizeof(firstp)); memset(dist,0,sizeof(dist)); for(int i = 1;i <= n;i++) { for(int j = 1;j <= A[i];j++) { if(firstp[K[i][j]] == 0) { firstp[K[i][j]] = i; dist[s][i] += P[K[i][j]]; } else { dist[firstp[K[i][j]]][i] = INF; firstp[K[i][j]] = i; } } dist[i][t] = B[i]; }}int flow[maxn][maxn]; //流量int alpha[maxn],pre[maxn]; //每个点的可改进量和每个点的前驱int q[maxn],qs,qe; //队列//Ford-Fulkersonvoid solve() { memset(flow,0,sizeof(flow)); alpha[s] = INF; while(1) { //初始化标号 for(int i = 1;i <= t;i++) pre[i] = -2; pre[s] = -1; //初始化队列,源点入列 qs = 0; qe = 1; q[qs] = s; //标号过程 while(qs < qe && pre[t] == -2) { //终点没有被标号并且队列非空 int v = q[qs]; qs++; //printf("now v is %d\n",v); for(int i = 1;i <= t;i++) { //如果目标点没有被标号并且还有残余流量 if(pre[i] == -2 && dist[v][i] - flow[v][i] != 0) { pre[i] = v; alpha[i] = min(alpha[v],dist[v][i] - flow[v][i]); q[qe++] = i; } } } //没有找到到汇点的增广路,退出 if(pre[t] == -2) { break; } //逆向更新 int aval = alpha[t]; for(int i = t;pre[i] != -1;i = pre[i]) { flow[pre[i]][i] += aval; flow[i][pre[i]] = -flow[pre[i]][i]; } } //统计流量 int ans = 0; for(int i = 1;i <= n;i++) { ans += flow[i][t]; } printf("%d\n",ans);}int main() { while(scanf("%d%d",&m,&n) != EOF) { input(); init(); solve(); } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。