首页 > 其他分享 >[SCOI2007] 修车

[SCOI2007] 修车

时间:2024-05-19 11:51:24浏览次数:9  
标签:int flw vis lst 修车 SCOI2007 dis

考虑将修车师傅放在一边,顾客放在一边。

对于第 \(i\) 辆车,让第 \(j\) 个修车师傅来修,放在了倒数第 \(l\) 个,那么他产生的贡献即为 \(t_{i,j}\times l\)。

我们可以将每个修车师傅拆成 \(n\) 个点,第 \(l\) 个点表示修车师傅的倒数第 \(l\) 个位置,跑费用流即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1005,M=1e5+5;
int n,m,s,t,k=1,h[N],vis[N];
int to[M],nxt[M],w[M],f[M];
int lst[N],flw[N],dis[N];
void add(int x,int y,int z,int a){
    w[++k]=z;f[k]=a;to[k]=y;
    nxt[k]=h[x];h[x]=k;
    f[++k]=-a;to[k]=x;
    nxt[k]=h[y];h[y]=k;
}queue<int>q;
int spfa(){
    while(q.size()) q.pop();
    memset(lst,-1,sizeof(lst));
    memset(vis,0,sizeof(vis));
    memset(dis,127,sizeof(dis));
    flw[s]=1e9;dis[s]=0;q.push(s);
    while(q.size()){
        int x=q.front();
        q.pop();vis[x]=0;
        for(int i=h[x];i;i=nxt[i]){
            int y=to[i],vl=w[i];
            if(vl&&dis[y]>dis[x]+f[i]){
                lst[y]=i;
                flw[y]=min(flw[x],vl);
                dis[y]=dis[x]+f[i];
                if(!vis[y])
                    q.push(y),vis[y]=1;
            }
        }
    }return lst[t]!=-1;
}int mxflw,mncst;
void MCMF(){
    while(spfa()){
        mxflw+=flw[t];
        mncst+=dis[t]*flw[t];
        for(int i=t;i!=s;i=to[lst[i]^1])
            w[lst[i]]-=flw[t],w[lst[i]^1]+=flw[t];
    }
}signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>m>>n;t=n+n*m+1;
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
            add(s,i*n+j,1,0);
    for(int i=1;i<=n;i++) add(i,t,1,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            int x;cin>>x;
            for(int l=1;l<=n;l++)
                add(j*n+l,i,1,l*x);
        }
    MCMF();printf("%.2lf",mncst*1.0/n);
    return 0;
}//spfa:它没有死透

标签:int,flw,vis,lst,修车,SCOI2007,dis
From: https://www.cnblogs.com/chang-an-22-lyh/p/18200190/scoi2007-xiuche_tj

相关文章

  • [SCOI2007] 蜥蜴 题解
    发现实际上就是在求有多少只蜥蜴能逃出来。发现可以将柱子拆成入点和出点两部分,自己的出点向别人的入点连边,自己的入点向自己的出点连边。最后再加一个超级源点\(S\),连接所有有蜥蜴的柱子入点;再加一个超级汇点\(T\),连接所有能够跳出地图的柱子。我们猛然发现:这个问题不就是求......
  • P2053 [SCOI2007] 修车
    题意有\(n\)个工人,\(m\)个工作。每个人给每个工作有\(t_{i,j}\)的花费。求每个工作的最小平均花费。Sol直接连边跑费用流不好搞。考虑将每种工人在不同时间做的工作暴力建点。枚举\(k\)表示第\(i\)个工人在倒数第\(k\)个做\(j\)工作。这样仍然不好考虑贡献,......
  • [SCOI2007] 修车
    [SCOI2007]修车题目描述同一时刻有\(N\)位车主带着他们的爱车来到了汽车维修中心。维修中心共有\(M\)位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这\(M\)位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。说明:顾客的等待时间......
  • P4163 [SCOI2007]排列
    Problem给一个数字串\(s\)和正整数\(d\),统计\(s\)有多少种不同的排列能被\(d\)整除(可以有前导\(0\))。多组数据。\(\left\verts\right\vert\le10,1\led\le1000,1\let\le15\)Input第一行一个整数\(t\),表示数据组数。接下来\(t\)行,每行一个数字串\(s\)......
  • NC20259 [SCOI2007]降雨量
    题目链接题目题目描述我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自......
  • P2470 [SCOI2007]压缩
    传送门区间DP好题,看到这题很容易想到设\(f[i][j]\)为区间\(i\)~\(j\)内的最短折叠,那么转移方程就为:\[f[i][j]=min_{k=i}^{j-1}(f[i][j],f[i][k]+f[k+1][j])\]然鹅这......
  • 【SCOI2007】k短路(A_)
    考虑用\(A^*\)维护这个东西,由于其它题解都讲得很清楚\(A^*\)的原理了,我就在这里说一下这题需要注意的地方。按照\(A^*\)的套路,我们要把估价函数设为当前点到\(b\)......