#78-【最小费用最大流】最小费用最大流

Description

求一个网络的最小费用最大流

【输入格式】

第1行:2个空格分开的整数N,M。N是节点数,M是边数。N≤500,M≤N^2/2

第2..M+1行:每行4个空格分开的整数A,B,C,D,表示了一条有向边A-B,边的容量为C,费用为D,1为源点,N为汇点

【输出格式】

第1行:一个整数,表示最小费用

 

【输入样例】

4 5
2 4 30 2
3 4 20 3
2 3 20 1
1 3 40 5
1 2 30 5

 

【输出样例】

370

很模板......

#include 
#include 
#include 

#define SIZE 510
#define INF 1e+09

using namespace std;

struct edge
{
	int to, cap, cost, reverse;
};

vector graph[SIZE];
int pre[SIZE], dis[SIZE], edgeindex[SIZE], sink;
bool inqueue[SIZE];

bool spfa(int s)
{
	queue q;
	int u, v, i;
	
	memset(pre, -1, sizeof (pre));
	for (i = 0; i < SIZE; ++i)
	{
		dis[i] = INF;
	}
	memset(edgeindex, -1, sizeof (edgeindex));
	memset(inqueue, false, sizeof (inqueue));
	dis[s] = 0;
	q.push(s);
	inqueue[s] = true;
	while (!q.empty())
	{
		u = q.front();
        /* 如果是汇点,此处不能退出,因为没有得到所有的dis[i],留下隐患 */
		q.pop();
		inqueue[u] = false;
		for (i = 0; i < graph[u].size(); ++i)
		{
			v = graph[u][i].to;
			if ((graph[u][i].cap > 0) && (dis[v] > dis[u] + graph[u][i].cost))
			{
				dis[v] = dis[u] + graph[u][i].cost;
				pre[v] = u;
				edgeindex[v] = i;
				if (!inqueue[v])
				{
					q.push(v);
					inqueue[v] = true;
				}
			}
		}
	}
	
	return (dis[sink] != INF);
}

int mincostmaxflow(int s) // 最小费用最大流模板函数
{
	int u, v, maxflow = 0, delta, mincost = 0, i;
	
	while (spfa(s))
	{
		delta = INF;
		for (v = sink; v != s; v = u)
		{
			u = pre[v];
			i = edgeindex[v];
			delta = min(delta, graph[u][i].cap);
		}
		for (v = sink; v != s; v = u)
		{
			u = pre[v];
			i = edgeindex[v];
			mincost += delta * graph[u][i].cost;
			graph[u][i].cap -= delta;
			graph[v][graph[u][i].reverse].cap += delta;
		}
		maxflow += delta;
	}
	
	return mincost;
}

int main(int argc, char** argv)
{
	int n, m, u, v, cap, cost;
	
	scanf("%d%d", &n, &m);
	while (m--)
	{
		scanf("%d%d%d%d", &u, &v, &cap, &cost);
		graph[u].push_back({v, cap, cost, graph[v].size()});
		graph[v].push_back({u, 0, -cost, graph[u].size() - 1}); // 建图
	}
	
	sink = n; // 汇点
	
	printf("%d", mincostmaxflow(1));
	
	return 0;
}

 

你可能感兴趣的:(刷题,gdgzoi刷题)