uva10746(最小费用最大流)

来源:互联网 发布:mysql中的主键是什么 编辑:程序博客网 时间:2024/05/16 09:50

题目的意思就是有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);}}


0 0