早上状态不好,虚树搞崩只好来刷网络流了qwq。
(然后我犹豫几秒之后看了题解)
使用拆点大法把工人拆成n*m个点,然后每个点代表每个时间段的工人,
然后从车到每个工人点连一条边,权值是耽误的时间,就是这个车在这个时间段用这个工人所用的时间。
然后跑费用流。
(然后我太菜了费用流忘了怎么打了,回头一翻自己博客发现居然只是一周之前学的东西)
#include<cstdio> #include<cstdlib> #include<cctype> #include<algorithm> #include<cstring> #include<queue> #define maxn 30000 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } inline int count(int i){ return i&1?i+1:i-1; } int dfn[maxn]; bool vis[maxn]; int Start,End; struct Edge{ int from,next,to,dis,val,flow; }edge[maxn*5]; int head[maxn],num; inline void addedge(int from,int to,int dis,int val){ edge[++num]=(Edge){from,head[from],to,dis,val,0}; head[from]=num; } inline void add(int from,int to,int dis,int val){ addedge(from,to,dis,val); addedge(to,from,-dis,0); } struct Ans{ int dis,val; Ans(){dis=val=0;} }; int dis[maxn]; int pre[maxn]; int flow[maxn]; Ans spfa(){ Ans ans; memset(dis,127/3,sizeof(dis)); int Max=dis[0]; dis[Start]=0; flow[Start]=0x7fffffff; queue<int>q; q.push(Start); while(!q.empty()){ int from=q.front();q.pop();vis[from]=0; for(int i=head[from];i;i=edge[i].next){ int to=edge[i].to; if(edge[i].dis+dis[from]>=dis[to]||edge[i].val==edge[i].flow) continue; dis[to]=dis[from]+edge[i].dis; pre[to]=i; flow[to]=min(flow[from],edge[i].val-edge[i].flow); if(!vis[to]){ vis[to]=1; q.push(to); } } } if(dis[End]==Max) return ans; int now=End; ans.val=flow[End]; ans.dis=dis[End]; while(now!=Start){ int ret=pre[now]; edge[ret].flow+=flow[End]; edge[count(ret)].flow-=flow[End]; now=edge[ret].from; } return ans; } double ans; int main(){ int m=read(),n=read();End=maxn-2; for(int i=1;i<=n;++i) add(Start,i,0,1); for(int j=1;j<=m;++j) for(int i=1;i<=n;++i) add((i-1)*m+n+j,End,0,1); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ int x=read(); for(int k=1;k<=n;++k) add(i,(k-1)*m+j+n,k*x,1); } while(1){ Ans now=spfa(); if(!now.val) break; ans+=now.dis*now.val; } printf("%.2lf",ans/n); return 0; }