zoukankan      html  css  js  c++  java
  • 题解 [SCOI2007]修车

    题面

    解析

    这题要拆点。。

    首先,证明一个式子:

    设修理员M修了N辆车,

    且修每辆车的时间为W1,W2....WN。

    那么,这个修理员一共花的时间就为:W1*N+W2*(N-1)+...+WN*1。

    因此,若i号修理员修第j辆车的时间为c[i][j],

    将c[i][j]拆成1...n个点,

    将其中第k个点与j号顾客(j号车)相连,

    费用为c[i][j]*k,

    最后将修理员与源点相连,顾客与汇点相连(反过来也可以),

    流量为1,费用为0。

    跑费用流就行了。

    上AC代码:

    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    inline int read(){
        int sum=0,f=1;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
        return f*sum;
    }
    
    const int INF=0x3f3f3f3f;
    struct node{
        int to,next,v,w;
    }e[100001];
    struct hh{
        int fa,edge;
    }pre[100001];
    int n,m,s,t;
    int c[101][101]/*第i辆车给第j个人修的时间*/;
    int head[100001],cnt=1;
    int d[100001],inq[100001],mi[100001];
    
    void add(int x,int y,int v,int w){
        //printf("%d -> %d : %d
    ",x,y,w);
         e[++cnt].to=head[x];
        e[cnt].next=y;
        e[cnt].v=v;e[cnt].w=w;
        head[x]=cnt;
        e[++cnt].to=head[y];
        e[cnt].next=x;
        e[cnt].v=0;e[cnt].w=-w;
        head[y]=cnt;
    }
    
    bool spfa(){
        memset(d,0x3f,sizeof(d));
        memset(inq,0,sizeof(inq));
        memset(mi,0x3f,sizeof(mi));
        queue <int> que;
        que.push(s);
        d[s]=0;
        while(!que.empty()){
            int x=que.front();
            que.pop();
            inq[x]=0;
            for(int i=head[x];i;i=e[i].to){
                int k=e[i].next;
                if(!e[i].v||d[k]<=d[x]+e[i].w) continue;
                d[k]=d[x]+e[i].w;
                pre[k].fa=x;pre[k].edge=i;
                mi[k]=min(mi[x],e[i].v);
                if(!inq[k]) que.push(k);
                inq[k]=1;
            }
        }
        return d[t]!=INF;
    }
    
    void EK(){
        int ans=0;
        while(spfa()){
            for(int i=t;i!=s;i=pre[i].fa){
                e[pre[i].edge].v-=mi[t];
                e[pre[i].edge^1].v+=mi[t];
            }
            ans+=d[t]*mi[t];
        }
        printf("%.2lf
    ",(double)((double)ans/(double)n));
    }
    
    int main(){
    //    freopen("fixed.in","r",stdin);
    //    freopen("fixed.out","w",stdout);
        m=read();n=read();
        s=1+(m+2)*n;t=2+(m+2)*n;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                c[i][j]=read();
            }
        }
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                add(s,i+m*j,1,0);
                for(int k=1;k<=n;k++){
                    add(i+m*j,k+m*n+n,1,c[k][i]*j);
                }
            }
        }
        for(int i=1;i<=n;i++){
            add(i+m*n+n,t,1,0);
        }
        EK();
        return 0;
    }
  • 相关阅读:
    java通过ftp和sftp上传war包上传到Linux服务器实现自动重启tomcat的脚本代码
    linux 下 nginx 启动服务器 80端口被占用问题
    ZooKeeper伪分布集群安装及使用 RMI+ZooKeeper实现远程调用框架
    nginx+tomcat+redis的集群+session共享
    java 实现mysql数据库导出
    SpringQtz 时间任务调度
    java.lang.OutOfMemoryError: Java heap space解决方法 (有问题咨询加微信)
    tomcat 大并发报错 Maximum number of threads (200) created for connector with address null and port 8080
    linux下安装svn
    Nginx 性能优化
  • 原文地址:https://www.cnblogs.com/zsq259/p/10524912.html
Copyright © 2011-2022 走看看