bzoj1070: [SCOI2007]修车
同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
费用流,把m个人中的每个人拆分成n个代表是第k个开始维修的,然后和每两个挨个连边费用是原来的*k,人和源点连边,车和汇点连边,流量都是1,费用都是0,跑
费用流即可
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define vi vector<int> #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pli pair<ll,int> #define pii pair<int,int> #define cd complex<double> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=200000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; struct edge{ int to,Next,c; int cost; }e[maxn]; int cnt,head[N]; int s,t; int dis[N],pre[N],path[N]; bool vis[N]; void add(int u,int v,int c,int cost) { e[cnt].to=v; e[cnt].c=c; e[cnt].cost=cost; e[cnt].Next=head[u]; head[u]=cnt++; e[cnt].to=u; e[cnt].c=0; e[cnt].cost=-cost; e[cnt].Next=head[v]; head[v]=cnt++; } bool spfa() { memset(pre,-1,sizeof pre); memset(dis,inf,sizeof dis); memset(vis,0,sizeof vis); dis[s]=0; vis[s]=1; queue<int>q; q.push(s); while(!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];~i;i=e[i].Next) { int te=e[i].to; if(e[i].c>0&&dis[x]+e[i].cost<dis[te]) { dis[te]=dis[x]+e[i].cost; pre[te]=x; path[te]=i; if(!vis[te])q.push(te),vis[te]=1; } } } return pre[t]!=-1; } int mincostmaxflow() { int cost=0,flow=0; while(spfa()) { int f=inf; for(int i=t;i!=s;i=pre[i]) if(e[path[i]].c<f) f=e[path[i]].c; flow+=f; cost+=dis[t]*f; for(int i=t;i!=s;i=pre[i]) { e[path[i]].c-=f; e[path[i]^1].c+=f; } } return cost; } void init() { memset(head,-1,sizeof head); cnt=0; } inline int read(){ int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w; } int main() { init(); int m=read(),n=read(); s=n*(m+1)+1,t=n*(m+1)+2; for(int i=1;i<=n;i++) { add(n*m+i,t,1,0); for(int j=1;j<=m;j++) { add(s,(j-1)*n+i,1,0); int x=read(); for(int k=1;k<=n;k++) { add((j-1)*n+k,n*m+i,1,k*x); } } } printf("%.2f\n",mincostmaxflow()*1.0/n); return 0; } /*********************** 2 1 1 2 ***********************/