zoukankan      html  css  js  c++  java
  • BZOJ 1070: [SCOI2007]修车 [最小费用最大流]

    1070: [SCOI2007]修车

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 4936  Solved: 2032
    [Submit][Status][Discuss]

    Description

      同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同
    的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最
    小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

    Input

      第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人
    员维修第i辆车需要用的时间T。

    Output

      最小平均等待时间,答案精确到小数点后2位。

    Sample Input

    2 2
    3 2
    1 4

    Sample Output

    1.50

    HINT

    数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)


    理解错了题意:每个人可以修多辆车
     
    每个人拆成n个点,对于他修的倒数第一辆代价就是1*time,倒数第二辆就是2*time,一次类推
    每个点都像车连一条容量为1,代价为以上时间的边
    s连所有人,t连所有车,跑费用流即可
     
    注意先m后n
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int N=1005,M=1e5+5,INF=1e9;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    int n,m,a[N][N],s,t;
    struct edge{
        int v,ne,c,f,w;
    }e[M<<1];
    int cnt,h[N];
    inline void ins(int u,int v,int c,int w){
        cnt++;
        e[cnt].v=v;e[cnt].c=c;e[cnt].f=0;e[cnt].w=w;
        e[cnt].ne=h[u];h[u]=cnt;
        cnt++;
        e[cnt].v=u;e[cnt].c=0;e[cnt].f=0;e[cnt].w=-w;
        e[cnt].ne=h[v];h[v]=cnt;
    }
    inline int id(int i,int j){return (i-1)*n+j;}
    void build(){
        s=0;t=m*n+n+1;int num=m*n;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++){
                int t=id(i,j);
                ins(s,t,1,0);
                for(int k=1;k<=n;k++) ins(t,num+k,1,a[i][k]*j);
            }
        for(int i=1;i<=n;i++) ins(num+i,t,1,0);
    }
    
    
    int q[N],head,tail,d[N],inq[N],pre[N],pos[N];
    inline void lop(int &x){if(x==N) x=1;else if(x==0) x=N-1;}
    bool spfa(){
        memset(d,127,sizeof(d));
        memset(inq,0,sizeof(inq));
        head=tail=1;
        q[tail++]=s;inq[s]=1;d[s]=0;
        pre[t]=-1;
        while(head!=tail){
            int u=q[head++];inq[u]=0;lop(head);
            for(int i=h[u];i;i=e[i].ne){
                int v=e[i].v,w=e[i].w;
                if(e[i].c>e[i].f&&d[v]>d[u]+w){
                    d[v]=d[u]+w;
                    pos[v]=i;pre[v]=u;
                    if(!inq[v]){
                        inq[v]=1;
                        if(d[v]<d[q[head]]) head--,lop(head),q[head]=v;
                        else q[tail++]=v,lop(tail);
                    }
                }
            }
        }
        return pre[t]!=-1;
    }
    int mcmf(){
        int flow=0,cost=0;
        while(spfa()){
            int f=INF;
            for(int i=t;i!=s;i=pre[i]) f=min(f,e[pos[i]].c-e[pos[i]].f);
            flow+=f;cost+=d[t]*f;
            for(int i=t;i!=s;i=pre[i]){
                int p=pos[i];
                e[p].f+=f;
                e[((p-1)^1)+1].f-=f;
            }
        }
        return cost;
    }
    int main(){
        m=read();n=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++) a[j][i]=read();//
        build();
        printf("%.2f",(double)mcmf()/n);
    }
  • 相关阅读:
    小数的进制转换
    水题 O
    水题 J
    水题T,二进制转16进制
    水题B
    水题C
    HDU 2042
    HDU 2041
    Index For SQL Server
    Learning Note For Angular
  • 原文地址:https://www.cnblogs.com/candy99/p/6188118.html
Copyright © 2011-2022 走看看