由题意可知一个人不可以同时修很多辆车 所以如果一个人修很多车最小的话 那一定有一个顺序就是 修第一辆车 第二辆车 第三辆车。。。。 修第一辆车的时候 第二辆 ~ 第n辆都在等第一辆修 所以 时间就是为 第一辆的时间 * n 第二辆的时候就是 第二辆的时间 * n - 1 以此类推
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 70 * 100,M = N * N * 2;
int n,m,S,T;
int head[N],to[M],last[M],c[M],w[M],cnt = 1;
void add(int a,int b,int c1,int d){
to[++cnt] = b;
c[cnt] = c1;
w[cnt] = d;
last[cnt] = head[a];
head[a] = cnt;
to[++cnt] = a;
c[cnt] = 0;
w[cnt] = -d;
last[cnt] = head[b];
head[b] = cnt;
}
int dist[N],flag[N],incf[N],ne[N];
bool spfa(){
memset(dist,0x3f,sizeof dist);
memset(incf,0,sizeof incf);
queue<int>q;
q.push(S);
dist[S] = 0;incf[S] = 0x3f3f3f3f;
while(q.size()){
int p = q.front();
q.pop();
flag[p] = 0;
for(int i = head[p]; i != -1; i = last[i]){
int j = to[i];
if(c[i] && dist[j] > dist[p] + w[i]){
dist[j] = dist[p] + w[i];
incf[j] = min(incf[p],c[i]);
ne[j] = i;
if(!flag[j]){
flag[j] = 1;
q.push(j);
}
}
}
}
return incf[T] > 0;
}
int ek(){
int sum = 0;
while(spfa()){
int k = incf[T];
sum += k * dist[T];
for(int i = T; i != S; i = to[ne[i] ^ 1]){
c[ne[i]] -= k;
c[ne[i] ^ 1] += k;
}
}
return sum;
}
int main(){
cin >> n >> m;
memset(head,-1,sizeof head);
S = 0,T = n * m + m + 1;
for(int i = 1; i <= m; i++){
add(S,i,1,0);
}
for(int i = 1; i <= m; i++){ //m辆车
for(int j = 1; j <= n; j++){ //第j个人对 第i辆车的时间
int x;
cin >> x;
for(int k = 1; k <= m; k++){ //倒数第k辆车修
add(i,m + (j - 1) * m + k,1,x * k);
}
}
}
for(int i = 1; i <= n * m; i++){
add(i + m,T,1,0);
}
printf("%.2lf\n",ek() * 1.0 / m);
return 0;
}``