rt,调不动了(
#include<bits/stdc++.h>
using namespace std;
int n,m;
int s,t;
const int Max=605;
const int inf=1e9+7;
using pii=pair<int,int>;
struct Edge
{
int v;
int flow;
int cost;
int id;
};
vector<Edge> edge[Max];
void addedge(int u,int v,int flow,int cost)
{
int idu=edge[u].size();
int idv=edge[v].size();
edge[u].push_back((Edge){v,flow,cost,idv});
edge[v].push_back((Edge){u,0,-cost,idu});
}
int h[Max];
bool vis[Max];
void spfa()
{
queue<int> q;
fill(h,h+t+1,inf);
h[s]=0;
q.push(s);
vis[s]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(auto e:edge[u])
{
int v=e.v;
if(e.flow&&h[v]>h[u]+e.cost)
{
h[v]=h[u]+e.cost;
if(!vis[u])
{
vis[u]=1;
q.push(u);
}
}
}
}
}
int dis[Max];
pii pre[Max];
bool dij()
{
priority_queue<pii,vector<pii>,greater<pii> > q;
fill(vis,vis+t+1,0);
fill(dis,dis+t+1,inf);
dis[s]=0;
q.push((pii){dis[s],s});
while(!q.empty())
{
int u=q.top().second;
q.pop();
if(vis[u])
{
continue;
}
vis[u]=1;
for(int i=0;i<edge[u].size();i++)
{
const Edge e=edge[u][i];
if(!e.flow)
{
continue;
}
int v=e.v;
int w=e.cost+h[u]-h[v];
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
pre[v]=(pii){u,i};
q.push((pii){dis[v],v});
}
}
}
return dis[t]^inf;
}
int mcmf()
{
spfa();
int cost=0,flow;
while(dij())
{
for(int i=1;i<=n;i++)
{
h[i]+=dis[i];
}
flow=inf;
for(int cur=t;cur^s;cur=pre[cur].first)
{
flow=min(flow,edge[pre[cur].first][pre[cur].second].flow);
}
for(int cur=t;cur^s;cur=pre[cur].first)
{
auto &e=edge[pre[cur].first][pre[cur].second];
auto &fe=edge[e.v][e.id];
e.flow-=flow;
fe.flow+=flow;
cost+=e.cost*flow;
}
}
return cost;
}
int main()
{
cin>>m>>n;
s=0,t=n*m+n+1;
for(int i=1;i<=n;i++)
{
addedge(s,i,1,0);
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
addedge(i*n+j,t,1,0);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int cost;
cin>>cost;
for(int k=1;k<=n;k++)
{
addedge(i,j*n+k,1,cost*k);
}
}
}
cout<<fixed<<setprecision(2)<<1.0*mcmf()/n;
return 0;
}