uva10746(最小费用最大流)

本文介绍了一种解决特定问题的最小费用最大流算法实现,该问题涉及多个警察分配到不同银行进行巡逻的情景。通过建立合适的图模型,并使用超级源点和超级汇点连接警察与银行,最终通过算法计算出最小费用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目的意思就是有n家银行被抢劫.然后有m个警察在巡逻.

然后下面n行,每行m个元素.是每个警察到这个银行要多少时间.

首先建图.

用超级源点把警察全都连起来,容量为一,然后用超级汇点把银行全都连起来,容量为1.

然后把警察和银行之间连起来,容量为1,费用为所需时间(注意费用的反向边,cost[v][u] = - cost[u][v])

然后套用最小费用最大流模板算法.

最后输出结果因为精度要-1e-9;


AC代码:


#include<stdio.h>
#include<string.h>
#include<queue>
#include<math.h>
using namespace std;
const int N = 50;
const double INF = 1000000000.0;
int cap[N][N];
int flow[N][N];
int p[N];
double cost[N][N];
int n,m,f;
double c,temp;
double ek(int t) {
	queue<int> q;
	double d[N];
	memset(flow , 0 , sizeof(flow));
	c = 0;
	f = 0;
	while(1) {
		int vis[N];
		memset(vis , 0 ,sizeof(vis));
		for (int i = 0 ; i <= t ;i++) 
			d[i] = INF;
		d[0] = 0.0 ;
		q.push(0);
		while(!q.empty()) {
			int u = q.front();
			q.pop();
			vis[u] = 0;
			for (int v = 0 ; v <= t ;v++) {
				if (cap[u][v] > flow[u][v] && d[v] > d[u] + cost[u][v]) {
					d[v] = d[u] + cost[u][v];
					p[v] = u;
					if (!vis[v]) {
						vis[v] = 1;
						q.push(v);
					}
				}
			}
		}
		if (d[t] == INF) break;
		int a = 0x3f3f3f3f;
		for (int u = t ; u != 0 ; u = p[u]) 
			a = a < cap[p[u]][u] - flow[p[u]][u] ? a : cap[p[u]][u] - flow[p[u]][u];
		for (int u = t ; u != 0 ; u = p[u]) {
			flow[p[u]][u] += a;
			flow[u][p[u]] -= a;
		}
		c += d[t] * a;
		f += a;
	}
	return c;
}
int main () {
	while(scanf("%d%d",&n,&m) && n) {
		memset(cap , 0 ,sizeof(cap));
		for (int i = 1 ; i <= n ;i++) {
			for (int j = 1 ; j <= m ;j++) {
				scanf("%lf",&temp);
				cap[j][i + m] = 1;
				cost[j][i + m] = temp;
				cost[i + m ][j] = -temp;
			}
		}
		for (int i = 1 ; i <= m ;i++) {
			cap[0][i] = 1;
		}
		for (int i = m + 1 ; i <= n + m ; i++) {
			cap[i][n + m + 1] = 1;
		}
		double res = ek(n + m + 1);
		printf("%.2lf\n",res / n + 1e-9);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值