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

    最小费用最大流。

    这道题的特点在于每个修车的人所需要等待的时间要加上之前这个技术人员维修车的时间。

    直观地我们可以每个技术人员建造n个点,费用分别为k*t(k=1,2,3…)(t为维修时间)。

    但是这样很可能会超时,我们又发现,因为总共只有n个人来修车,我们每次用过每个修车人员后,再临时增加点,就可以避免浪费。

    决策时,就变成了这个技术人员倒数第几个修这个车。

    语言比较混乱,但这道题是好题。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 10000 + 10;
    const int maxm = 1000000 + 10;
    const int inf = 0x3f3f3f3f;
    
    int g[maxn],v[maxm],next[maxm],f[maxm],c[maxm],eid;
    int id[10][maxn],cnt[10],vid;
    int dist[maxn],pre[maxn];
    int q[maxm],l,r;
    bool inque[maxn];
    int t[110][20];
    int m,n,res,S,T;
    
    void addedge(int a,int b,int C) {
        v[eid]=b; f[eid]=1; c[eid]=C; next[eid]=g[a]; g[a]=eid++;
        v[eid]=a; f[eid]=0; c[eid]=-C; next[eid]=g[b]; g[b]=eid++;
    }
    
    void build() {
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++)
            scanf("%d",&t[i][j]);
        memset(g,-1,sizeof(g));
        S=0; T=maxn-1; vid=n;
        for(int i=1;i<=n;i++) addedge(S,i,0);
        for(int p=1;p<=m;p++) {
            id[p][++cnt[p]]=++vid;
            addedge(vid,T,0);
            for(int i=1;i<=n;i++) 
                addedge(i,vid,t[i][p]);        
        }
    }
    
    void augment() {
        for(int i=T;i!=S;i=v[pre[i]^1]) {
            f[pre[i]]--;
            f[pre[i]^1]++;
        }
        res+=dist[T];
    }
    
    int SPFA() {
        memset(dist,0x3f,sizeof(dist));
        memset(pre,-1,sizeof(pre));
        l=r=0;
        dist[S]=0;
        inque[q[r++]=S]=1;
        int u;
        while(l<r) {
            inque[u=q[l++]]=0;
            for(int i=g[u];~i;i=next[i]) 
            if(f[i] && dist[v[i]]>dist[u]+c[i]) {
                dist[v[i]]=c[i]+dist[u];
                pre[v[i]]=i;
                if(!inque[v[i]]) inque[q[r++]=v[i]]=1;
            }
        }
        augment();
        return v[pre[T]^1];
    }
    
    bool alter(int x) {
        int p;
        for(p=1;p<=m;p++) if(id[p][cnt[p]]==x) break;
        id[p][++cnt[p]]=++vid;
        addedge(vid,T,0);
        for(int i=1;i<=n;i++) 
            addedge(i,vid,t[i][p]*cnt[p]);    
    }
    
    void solve() {
        for(int i=1;i<=n;i++) alter(SPFA());
        printf("%.2lf
    ",1.0*res/n);
    }
    
    int main() {
        build();
        solve();
        return 0;    
    }
  • 相关阅读:
    GoJS实例1
    MAVEN 添加本地jar
    找不到xml、找不到类
    office365激活码序列号密钥:
    【转载】EF Core & Castle DynamicProxy基本用法(AOP)
    【转载】SQL Server
    【转载】对象克隆(C# 快速高效率复制对象另一种方式 表达式树转)
    [转载] Emit动态生成代码
    【转载】Windows 下搭建 wmi_exporter+Prometheus+Grafana 服务器性能监控平台
    Java RMI 使用
  • 原文地址:https://www.cnblogs.com/invoid/p/5570910.html
Copyright © 2011-2022 走看看