标签:
按顾客访问猪圈的顺序依次构图(顾客为结点),汇点->第一个顾客->第二个顾客->...->汇点
//第一道网络流
//Ford-Fulkerson
//Time:47Ms Memory:276K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
#define MAXN 105 //顾客
#define MAXM 1005 //猪圈
#define INF 0x3f3f3f3f
struct Arc {
int c, f;
}e[MAXN][MAXN];
int n, m;
int s, t;
int pig[MAXM], last[MAXM]; //last[]:猪圈当前顾客(0为源点,n+1为汇点)
int pre[MAXN]; //1.从哪一个结点
int alpha[MAXN]; //2.可改进量
void ford() //ford fulkerson
{
alpha[s] = INF; //源点可改进量无限
while (1) { //多次标号
memset(pre, -1, sizeof(pre)); //初始标号
queue<int> q;
q.push(s);
while (!q.empty() && pre[t] == -1) {
int cur = q.front(); q.pop();
for (int i = 1; i <= t; i++)
{
int tmp;
//tmp 为非0可保证邻接且保证有剩余流量
if (pre[i] == -1 && (tmp = e[cur][i].c - e[cur][i].f))
{
pre[i] = cur;
q.push(i);
alpha[i] = min(alpha[cur], tmp);
}
}
}
if (pre[t] == -1) return; //未找到增广路
for (int i = pre[t], j = t; i != -1; j = i, i = pre[i])
{
e[i][j].f += alpha[t];
e[j][i].f = -e[i][j].f;
}
}
}
int main()
{
//freopen("in.txt", "r", stdin);
memset(last, 0, sizeof(last));
memset(e, 0, sizeof(e));
scanf("%d%d", &m, &n);
s = 0; t = n + 1;
for (int i = 1; i <= m; i++)
scanf("%d", &pig[i]);
for (int i = 1; i <= n; i++)
{
int num; //钥匙数
scanf("%d", &num);
while (num--) {
int pn;
scanf("%d", &pn);
if (last[pn] == 0)
e[last[pn]][i].c += pig[pn];
else e[last[pn]][i].c = INF;
last[pn] = i;
}
scanf("%d", &e[i][t].c);
}
ford();
int maxFlow = 0;
for (int i = 1; i < t; i++)
maxFlow += e[i][t].f;
printf("%d\n", maxFlow);
return 0;
}
ACM/ICPC 之 网络流入门-Ford Fulkerson(POJ1149)
标签:
原文地址:http://www.cnblogs.com/Inkblots/p/5703024.html