这道题卡vector,改用链式向前星存图可以过,至于边数要开的尽可能大,否则超时。。。。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=3000;
int vis[maxn];
int dis[maxn];
int ma[60][60];
int pre[maxn];
int head[maxn],tol;
struct Lu
{
int to;
int flow;
int cost;
int next;
} edge[16000000];
int spfa(int s,int t)
{
for(int i=s; i<=t; i++)
{
pre[i]=-1;
dis[i]=inf;
vis[i]=0;
}
queue<int>Q;
int top,vlen;
Lu L;
dis[s]=0;
Q.push(s);
while(!Q.empty())
{
top=Q.front();
Q.pop();
vis[top]=0;
for(int i = head[top]; i != -1; i = edge[i].next)
{
L=edge[i];
if(L.flow>0&&dis[L.to]>dis[top]+L.cost)
{
dis[L.to]=dis[top]+L.cost;
pre[L.to]=i;
if(!vis[L.to])
{
Q.push(L.to);
vis[L.to]=1;
}
}
}
}
if(dis[t]==inf)return 0;
return 1;
}
void addedge(int u,int v,int flow,int cost)
{
edge[tol].to = v;
edge[tol].cost = cost;
edge[tol].flow = flow;
edge[tol].next = head[u];
head[u] = tol++;
edge[tol].to = u;
edge[tol].cost = -cost;
edge[tol].flow = 0;
edge[tol].next = head[v];
head[v] = tol++;
}
int MinCostMaxFlow(int s,int t)
{
int cost=0,minl=inf;
while(spfa(s,t))
{
minl=inf;
for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to])
{
minl=min(minl,edge[i].flow);
}
for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to])
{
edge[i].flow-=minl;
edge[i^1].flow+=minl;
cost+=minl*edge[i].cost;
}
}
return cost;
}
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
tol=0;
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
scanf("%d",&ma[i][j]);
}
}
for(int i=1; i<=n; i++)
{
addedge(0,i,1,0);
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
for(int k=1; k<=n; k++)
{
addedge(i,j*n+k,1,ma[i][j]*k);
}
}
}
int t=n*m+n+1;
for(int i=n+1; i<t; i++)
{
addedge(i,t,1,0);
}
printf("%.6f\n",(double)MinCostMaxFlow(0,t)/(double)n);
}
}