luogu P2053 [SCOI2007]修车 |费用流

题目描述

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

说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

输入格式

第一行有两个数M,N,表示技术人员数与顾客数。

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

输出格式

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


#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e4+10,M=2e5+10,inf=0x3f3f3f3f;
int n,m,s,t;
int nxt[M],head[N],go[M],edge[M],cost[M],tot=1;
inline void add(int u,int v,int o1,int o2){
    nxt[++tot]=head[u],head[u]=tot,go[tot]=v,edge[tot]=o1,cost[tot]=o2;
    nxt[++tot]=head[v],head[v]=tot,go[tot]=u,edge[tot]=0,cost[tot]=-o2;
}
int dis[N],ret;
bool vis[N];
inline bool spfa(){
    memset(dis,0x3f,sizeof(dis)); dis[s]=0;
    queue<int>q; q.push(s);
    while(q.size()){
        int u=q.front(); q.pop(); vis[u]=0;
        for(int i=head[u];i;i=nxt[i]){
            int v=go[i];
            if(edge[i]&&dis[v]>dis[u]+cost[i]){
                dis[v]=dis[u]+cost[i];
                if(!vis[v])q.push(v),vis[v]=1;
            }
        }
    }
    return dis[t]!=inf;
}
int dinic(int u,int flow){
    if(u==t)return flow;
    int rest=flow,k;
    vis[u]=1;
    for(int i=head[u];i&&rest;i=nxt[i]){
        int v=go[i];
        if(edge[i]&&!vis[v]&&dis[v]==dis[u]+cost[i]){
            k=dinic(v,min(rest,edge[i]));
            if(!k)dis[v]=-1;
            ret+=k*cost[i];
            edge[i]-=k;
            edge[i^1]+=k;
            rest-=k;
        }
    }
    vis[u]=0;
    return flow-rest;
}
int c[65][65];
signed main(){
    cin>>m>>n;
    t=n*m+n+1;

    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    scanf("%d",&c[i][j]);

    for(int i=1;i<=n*m;i++)add(s,i,1,0);

    for(int i=1;i<=m;i++)
    for(int j=1;j<=n;j++)
    for(int k=1;k<=n;k++){
        int now=(i-1)*n+k;
        add(now,j+n*m,1,c[j][i]*k);
    }
    for(int i=1;i<=n;i++)add(n*m+i,t,1,0);

    int flow=0,maxflow=0;
    while(spfa())
    while(flow=dinic(s,inf))maxflow+=flow;
    printf("%.2lf\n",1.0*ret/n);
}

原文地址:https://www.cnblogs.com/naruto-mzx/p/12210103.html

时间: 2024-11-02 04:26:56

luogu P2053 [SCOI2007]修车 |费用流的相关文章

P2053 [SCOI2007]修车 费用流

https://www.luogu.org/problemnew/show/P2053 题意 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 思路 左边放n个点,表示n辆车.右边放m * n个点,表示m个工人,拆除n个点表示不同阶段.即如果第i辆车连上了第m个工人的第k个阶段

bzoj 1070: [SCOI2007]修车 -- 费用流

1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 128 MB Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Input 第一行有两个m,n,表示技术人员数与顾客数. 接下来n行,每行m个整数.第

[BZOJ1070] [SCOI2007] 修车 (费用流 &amp; 动态加边)

Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Input 第一行有两个m,n,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. Output 最小平均等待时间,答案精确到小数点后2位

BZOJ SCOI 2007 修车 费用流

题目大意:有一些车和一些修车的人,给出每个人修每个车的时间,问所有人等待的最短平均时间是多少. 思路:记得POJ有一个和这个很像的题,做法是一样的.对于每个人修车的时候,我们只考虑他修车的时间对在它之后修车的人的时间的影响,因此我们只要考虑每一辆车是倒数第几个修的就可以了,然后朴素的建图,跑朴素的费用流,就可以过. CODE: #include <queue> #include <cstdio> #include <cstring> #include <ioman

[bzoj1070] [洛谷P2053] [SCOI2007] 修车

Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同 的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最 小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Input 第一行有两个m,n,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人 员维修第i辆车需要用的时间T. Output 最小平均等待时间,答案精确到小数点

BZOJ 1070 修车(费用流)

如果能想到费用流,这道题就是显然了. 要求所有人的等待平均时间最小,也就是所有人的总等待时间最小. 每辆车只需要修一次,所以s连每辆车容量为1,费用为0的边. 现在需要把每个人拆成n个点,把车和每个人的第k个点连一条容量为1,费用为cost[i][j]*k的边. 最后把每个人拆完后的点向汇点连一条容量为1,费用为0的边. #include<iostream> #include<cstdio> #include<cstring> #define inf 0x7ffffff

洛谷 P2053 [SCOI2007]修车

题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 输入输出格式 输入格式: 第一行有两个数M,N,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. 输出格式: 最小平均等待时间,答案精确到小数点后2位

P2053 [SCOI2007]修车 最小费用最大流

题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 输入输出格式 输入格式: 第一行有两个数M,N,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. 输出格式: 最小平均等待时间,答案精确到小数点后2位

P2053 [SCOI2007]修车

思路 很妙的网络流题目 最开始我简单的想直接把n个车的点和m个人员的点直接用cap=t(i,j)的边连起来,显然是假的,因为没有考虑到车主等待的时间长度 然后考虑分析将\(w_1,w_2,\dots,w_k\)个车主对总时间的贡献,总的等待时间是\(\sum_{i=1}^kw_i\times (k-i+1)\)让一个人在第i个位置修车时对总时间的贡献是\((n-i+1)\times w_i\) 所以搞出n*m代表第m个维修人员在n的时候维修一辆车的贡献,然后连边就行了 代码 #include <