zoukankan      html  css  js  c++  java
  • 「BZOJ1070」[SCOI2007]修车

    求平均时间最小就是求总时间最小

    假设每个顾客对应的技术人员已经分配好了

    那么技术人员在修某一辆车时对答案的贡献就是 time × 在排队的人数

    所以可以想到把技术人员拆成n个点{mi1,mi2 ,……,min }

    对于每个顾客,向mij连一条容量为1,花费为 time*j 的边

    求这个二分图的最大权匹配

    可以用KM算法或费用流

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1000,oo=1e9;
     4 int n,m,ss,tt;
     5 struct Edge{
     6     int from,to,flow,cap,cost;
     7     Edge(int _from=0,int _to=0,int _flow=0,int _cap=0,int _cost=0):from(_from),to(_to),flow(_flow),cap(_cap),cost(_cost){}
     8 };
     9 vector<Edge>edge;
    10 int edge_tot;
    11 vector<int>point[N];
    12 void add_edge(int f,int t,int c,int cc){
    13     edge.push_back(Edge(f,t,0,c,cc));
    14     point[f].push_back(edge_tot++);
    15     edge.push_back(Edge(t,f,0,0,-cc));
    16     point[t].push_back(edge_tot++);
    17     return;
    18 }
    19 int dis[N],pre[N];
    20 bool spfa(){
    21     memset(dis,127/2,sizeof(dis));
    22     queue<int>q;
    23     q.push(ss);
    24     dis[ss]=0;
    25     int x;
    26     while(!q.empty()){
    27         x=q.front();q.pop();
    28         for(int i=0;i<point[x].size();i++){
    29             Edge& e=edge[point[x][i]];
    30             if(e.cap>e.flow&&dis[e.to]>dis[x]+e.cost){
    31                 dis[e.to]=dis[x]+e.cost,pre[e.to]=point[x][i];
    32                 q.push(e.to);
    33             }
    34         }
    35     }
    36     return dis[tt]<oo;
    37 }
    38 int mincostmaxflow(){
    39     int now,minf,ans=0;
    40     while(spfa()){
    41         minf=oo,now=tt;
    42         while(now!=ss){
    43             minf=min(minf,edge[pre[now]].cap-edge[pre[now]].flow);
    44             now=edge[pre[now]].from;
    45         }
    46         now=tt,ans+=minf*dis[tt];
    47         while(now!=ss){
    48             edge[pre[now]].flow+=minf,edge[pre[now]^1].flow-=minf;
    49             now=edge[pre[now]].from;
    50         }
    51     }
    52     return ans;
    53 }
    54 int main(){
    55     int t1;
    56     scanf("%d%d",&m,&n);
    57     ss=n*m+n+1,tt=ss+1;
    58     for(int i=1;i<=n;i++)
    59         for(int j=1;j<=m;j++){
    60             scanf("%d",&t1);
    61             for(int k=0;k<n;k++) add_edge(m*n+i,k*m+j,1,t1*(k+1));
    62         }
    63     for(int i=1;i<=n;i++) add_edge(ss,i+m*n,1,0);
    64     for(int i=1;i<=m*n;i++) add_edge(i,tt,1,0);
    65     printf("%.2lf",1.0*mincostmaxflow()/n);
    66     return 0;
    67 }
  • 相关阅读:
    JAVA面试——设计模式
    CSS清除浮动
    CSS外边距
    baidu-ife
    笔记一则
    Atom
    校园网认证
    四月甘九-省
    Python sys.argv[]用法
    Python模块导入的方法
  • 原文地址:https://www.cnblogs.com/mycups/p/8527884.html
Copyright © 2011-2022 走看看