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