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

    1070: [SCOI2007]修车

    Time Limit: 1 Sec  Memory Limit: 128 MB

    Submit: 6231  Solved: 2652

    [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个点,(i,j)表示i员工倒数第j辆修的车,每辆车向这些点连边,表示i员工倒数第j辆修这辆车,流量为1,费用为i*x,x为该员工修这辆车的时间,乘i是因为倒数第i个修这辆车,那么对后i-1辆车都会多x的等待时间,会产生(i-1)*x的代价,所以总代价为i*x。

    源点向每辆车连边,流量为1,费用为0,每个点(i,j)向汇点连边,流量为1,费用为0。

    求最小费用最大流即可。

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    using namespace std;
    const int N=65,M=10,inf=0x3f3f3f3f;
    int m,n,s,t,k,ans;
    int head[N*M],vis[N*M],dis[N*M],cur[N*M],from[N*M];
    struct edge{
    	int u,v,flow,cost,next;
    }e[N*N*M*4];
    void addedge(int u,int v,int flow,int cost){
    	e[k]=(edge){u,v,flow,cost,head[u]};
    	head[u]=k++;
    	e[k]=(edge){v,u,0,-cost,head[v]};
    	head[v]=k++;
    }
    queue<int>q;
    bool spfa(){
    	for(int i=s;i<=t;i++){
    		vis[i]=0;
    		dis[i]=inf;
    		from[i]=-1;
    	}
    	dis[s]=0;
    	q.push(s);
    	vis[s]=1;
    	int u,v,flow,cost;
    	while(!q.empty()){
    		u=q.front();
    		q.pop();
    		vis[u]=0;
    		for(int i=head[u];i!=-1;i=e[i].next){
    			v=e[i].v,flow=e[i].flow,cost=e[i].cost;
    			if(flow&&dis[u]+cost<dis[v]){
    				dis[v]=dis[u]+cost;
    				from[v]=i;
    				if(!vis[v]){
    					q.push(v);
    					vis[v]=1;
    				}
    			} 
    		}
    	}
    	if(dis[t]!=inf)return true;
    	return false;
    }
    void mcf(){
    	while(spfa()){
    		int x=inf;
    		for(int i=from[t];i!=-1;i=from[e[i].u])
    			x=min(x,e[i].flow);
    		for(int i=from[t];i!=-1;i=from[e[i].u]){
    			e[i].flow-=x;
    			e[i^1].flow+=x;
    			ans+=e[i].cost*x;
    		}
    	}
    }
    int main(){
    	memset(head,-1,sizeof(head));
    	scanf("%d%d",&m,&n);
    	s=0,t=n+n*m+1;
    	for(int i=1;i<=n;i++){
    		addedge(s,i,1,0);
    	}
    	for(int i=1;i<=m;i++){
    		for(int j=1;j<=n;j++){
    			addedge(i*n+j,t,1,0);
    		}
    	}
    	int x;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			scanf("%d",&x);
    			for(int k=1;k<=n;k++){
    				addedge(i,j*n+k,1,x*k);
    			}
    		}
    	}
    	mcf();
    	printf("%.2lf
    ",(double)ans/n);
    	return 0;
    }
  • 相关阅读:
    SSL JudgeOnline 1194——最佳乘车
    SSL JudgeOnline 1457——翻币问题
    SSL JudgeOnlie 2324——细胞问题
    SSL JudgeOnline 1456——骑士旅行
    SSL JudgeOnline 1455——电子老鼠闯迷宫
    SSL JudgeOnline 2253——新型计算器
    SSL JudgeOnline 1198——求逆序对数
    SSL JudgeOnline 1099——USACO 1.4 母亲的牛奶
    SSL JudgeOnline 1668——小车载人问题
    SSL JudgeOnline 1089——USACO 1.2 方块转换
  • 原文地址:https://www.cnblogs.com/chezhongyang/p/7746060.html
Copyright © 2011-2022 走看看