按顾客访问猪圈的顺序依次构图(顾客为结点),汇点->第一个顾客->第二个顾客->...->汇点
//第一道网络流 //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; }
时间: 2024-10-11 03:49:38