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

    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个点,分别表示由这个技术人员按顺序第几个修理该车。
    然后二分图完美匹配就行。
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    const int BufferSize=1<<16;
    char buffer[BufferSize],*head,*tail;
    inline char Getchar() {
        if(head==tail) {
            int l=fread(buffer,1,BufferSize,stdin);
            tail=(head=buffer)+l;
        }
        return *head++;
    }
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=710;
    const int maxm=200010;
    const int inf=1e9;
    struct ZKW {
        long long cost,ans;
        int n,m,s,t,first[maxn],next[maxm];
        int d[maxn],inq[maxn];
        struct Edge {int from,to,flow,cost;}edges[maxm];
        void init(int n) {
            this->n=n;m=0;
            memset(first,-1,sizeof(first));
        }
        void AddEdge(int u,int v,int w,int c) {
            edges[m]=(Edge){u,v,w,c};next[m]=first[u];first[u]=m++;
            edges[m]=(Edge){v,u,0,-c};next[m]=first[v];first[v]=m++;
        }
        deque<int> Q;
        int BFS() {
            rep(i,1,n) d[i]=inf;
            Q.push_front(t);d[t]=0;
            while(Q.size()) {
                int x=Q.front();Q.pop_front();inq[x]=0;
                ren {
                    Edge& e=edges[i^1];
                    if(e.flow&&d[e.from]>d[x]+e.cost) {
                        d[e.from]=d[x]+e.cost;
                        if(!inq[e.from]) {
                            if(Q.size()&&d[e.from]<=d[Q.front()]) Q.push_front(e.from);
                            else Q.push_back(e.from);
                            inq[e.from]=1;
                        }
                    }
                    
                }
            }
            rep(i,0,m-1) edges[i].cost+=d[edges[i].to]-d[edges[i].from];
            cost+=d[s];return d[s]!=inf;
        }
        int vis[maxn];
        int DFS(int x,int a) {
            if(x==t||!a) {ans+=cost*a;return a;}
            int flow=0,f;vis[x]=1;
            ren {
                Edge& e=edges[i];
                if(e.flow&&!e.cost&&!vis[e.to]&&(f=DFS(e.to,min(a,e.flow)))) {
                    e.flow-=f;edges[i^1].flow+=f;
                    flow+=f;a-=f;if(!a) break;
                }
            }
            return flow;
        }
        long long solve(int s,int t) {
            this->s=s;this->t=t;ans=cost=0;
            while(BFS()) do memset(vis,0,sizeof(vis));while(DFS(s,inf));
            return ans;
        }
    }sol;
    int main() {
        int m=read(),n=read();
        int S=(m+1)*n+1,T=S+1;sol.init(T);
        rep(i,1,n) sol.AddEdge(S,i,1,0);
        rep(i,n+1,S-1) sol.AddEdge(i,T,1,0);
        rep(i,1,n) rep(j,1,m) {
            int val=read();
            rep(k,1,n) sol.AddEdge(i,j*n+k,1,val*k);
        }
        printf("%.2lf
    ",sol.solve(S,T)*1.0/n);
        return 0;
    }
    View Code
  • 相关阅读:
    软工实践结对作业第二次
    团队展示
    软件工程结对作业
    软工实践第二次作业
    栈的初步学习
    课程作业四
    作业
    课程作业2
    博客汇总目录
    Mybatis-plus学习笔记,基于springboot
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5075631.html
Copyright © 2011-2022 走看看