标签:开始 相同 cap 入门 index 起点 窗口 cout pop
// algorithm_minimum_cost_stream.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
//https://blog.csdn.net/qq_43824791/article/details/93238445
#include "pch.h"
#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define maxN 400
#define maxM 15000
struct Edge {
int head, tail;
int next;
int cap, flow;
int weight;
}edge[maxM*2];
int headArray[maxN];//各起点分别拥有的最新的边的号
int preArray[maxN];
int dist[maxN];
bool vst[maxN];
int index_edge;
int n, m, s, t;
void addedge(int head, int tail, int c, int w)
{
edge[index_edge].head = head;
edge[index_edge].tail = tail;
edge[index_edge].cap = c;
edge[index_edge].flow = 0;
edge[index_edge].weight = w;
edge[index_edge].next = headArray[head];
headArray[head] = index_edge++;
edge[index_edge].head = tail;
edge[index_edge].tail = head;
edge[index_edge].cap = 0;
edge[index_edge].flow = 0;
edge[index_edge].weight = -w;
edge[index_edge].next = headArray[tail];
headArray[tail] = index_edge++;
}
bool SPFA()
{
memset(dist, 0x3f, sizeof(dist));
memset(vst, 0, sizeof(vst));
queue<int >que;
dist[s] = 0;//这里就没设为1,s一般题目中都为1
vst[s] = 1;
que.push(s);
while (!que.empty())
{
int i = que.front();
que.pop();
vst[i] = 0;
for (int edg_index = headArray[i]; edg_index != -1; edg_index = edge[edg_index].next)
{
int j = edge[edg_index].tail;
if (edge[edg_index].cap > edge[edg_index].flow && dist[j] > dist[i] + edge[edg_index].weight)
{
dist[j] = dist[i] + edge[edg_index].weight;
preArray[j] = edg_index;//记住边的号
if (!vst[j])
{
vst[j] = 1;
que.push(j);
}
}
}
}
if (dist[t] != inf)
return true;
return false;
}
int costflow(int &flow)
{
int mincost = 0;
while (SPFA())
{
int delta = inf;
for (int j = t; j != s; j = edge[preArray[j]].head)
{
delta = min(delta, edge[preArray[j]].cap - edge[preArray[j]].flow);
}
for (int j = t; j != s; j = edge[preArray[j]].head)
{
edge[preArray[j]].flow += delta;
edge[preArray[j]+1].flow -= delta;
}
flow += delta;
mincost += (dist[t] * delta);//每一次迭代,所用的delta是相同的都是一部分增量
}
return mincost;
}
int main()
{
index_edge = 0;
memset(headArray, -1, sizeof(headArray));
cin >> n >> m;
s=1 ,t=n;
for (int i = 0; i < m; i++)
{
int a, b, c, w;
cin >> a >> b >> c >> w;
addedge(a, b, c, w);
}
int maxflow = 0;
int mincost = costflow(maxflow);
cout << maxflow<<" " << mincost;
// std::cout << "Hello World!\n";
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门提示:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
标签:开始 相同 cap 入门 index 起点 窗口 cout pop
原文地址:https://www.cnblogs.com/Jonn-Liu/p/11515593.html