也不是很难
2024-07-02 17:24:11
发布于:广东
9阅读
0回复
0点赞
这段代码是一个关于网络流问题的实现,使用了最小费用最大流算法(SPFA + 费用标号法)。主要解决的问题是如何安排每天的餐巾需求和清洗服务,使得总成本最小化。
主要结构和功能解析:
数据结构和变量定义:
使用了结构体 node 存储每条边的信息,包括起点、终点、流量、费用等。
last[] 数组用于存储每个节点的最后一条边的位置。
pre[] 数组记录最短路中的路径,pos[] 记录路径上的前驱节点。
dis[] 记录从起点到各节点的最短距离。
p[] 记录路径上的最小剩余容量。
图的构建:
ins() 函数用于向图中添加边,根据题目描述,构建了与餐巾相关的流网络。例如,从起点到每天晚上的脏餐巾节点,从每天白天的干净餐巾节点到汇点等。
SPFA算法:
spfa() 函数实现了单源最短路径算法(SPFA),用于找出从起点到汇点的最短路径,并计算路径上的最小剩余容量 p[] 和最短路径花费 dis[]。
最小费用最大流算法:
flow() 函数是主函数,通过多次调用 spfa() 函数来求解最小费用最大流问题,计算出总的最小成本。
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define INF 2147483647
#define LL long long
using namespace std;
queue<int> f;
int n, m, m1, t1, m2, t2, len = -1, st, ed;
struct node { int x, y, c, d, next; } a[100000];
int b[100000], last[100000], pre[100000], pos[100000], p[100000];
LL dis[100000];
bool bz[100000];
void ins(int x, int y, int c, int d) {
a[++len].x = x; a[len].y = y; a[len].c = c; a[len].d = d; a[len].next = last[x]; last[x] = len;
a[++len].x = y; a[len].y = x; a[len].c = 0; a[len].d = -d; a[len].next = last[y]; last[y] = len;
}
bool spfa() {
memset(bz, true, sizeof(bz));
bz[st] = false;
memset(dis, 63, sizeof(dis));
dis[st] = 0;
p[st] = INF;
f.push(st);
while (!f.empty()) {
int x = f.front();
bz[x] = true;
for (int i = last[x]; i > -1; i = a[i].next) {
int y = a[i].y;
if (a[i].c > 0 && dis[y] > dis[x] + a[i].d) {
dis[y] = dis[x] + a[i].d;
pos[y] = x;
pre[y] = i;
p[y] = min(p[x], a[i].c);
if (bz[y]) {
f.push(y);
bz[y] = false;
}
}
}
f.pop();
}
return dis[ed] < 4557430888798830399;
}
LL flow() {
LL ans = 0;
while (spfa()) {
ans += p[ed] * dis[ed];
for (int i = ed; i != st; i = pos[i]) {
a[pre[i]].c -= p[ed];
a[pre[i] ^ 1].c += p[ed];
}
}
return ans;
}
int main() {
int x;
scanf("%d", &n);
st = 0, ed = 2 * n + 1;
memset(last, -1, sizeof(last));
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
ins(st, i, x, 0);
ins(i + n, ed, x, 0);
}
scanf("%d %d %d %d %d", &m, &t1, &m1, &t2, &m2);
for (int i = 1; i <= n; i++) {
if (i + 1 <= n) ins(i, i + 1, INF, 0); // 每天晚上可以将脏餐巾留到第二天晚上
if (i + t1 <= n) ins(i, i + n + t1, INF, m1);
if (i + t2 <= n) ins(i, i + n + t2, INF, m2);
ins(st, i + n, INF, m);
}
printf("%lld", flow());
return 0;
}
这里空空如也
有帮助,赞一个