zoukankan      html  css  js  c++  java
  • [bzoj1070][SCOI2007]修车【费用流】

    【题目链接】
      http://www.lydsy.com/JudgeOnline/problem.php?id=1070
    【题解】
      建图方式还是挺神的。
      我们不考虑每辆车之前的等待花费,而是考虑每辆车对之后的车的影响,因此,我们把每辆车插到最前面。费用为×
      因此,把每个技术人员拆成n个点,每个点的流量限制为1,表示倒数第i个修的车。
      每辆车也建一个点,向每个计数人员的每个时间连边。费用为icost

    /* --------------
        user Vanisher
        problem
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    # define    M       100010
    # define    N       1010
    # define    MM      20
    # define    NN      100
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    struct node{
        int data,next,l,vote,re;
    }e[M];
    int place,head[N],dis[N],use[N],can[N],ned[N],frm[N],n,m,S,T,q[N],ti;
    int mp[MM][NN],pin[MM][NN],p[NN];
    ll ans;
    void build(int u, int v, int l, int w){
        e[++place].data=v; e[place].next=head[u]; head[u]=place; e[place].vote=w; e[place].l=l; e[place].re=place+1;
        e[++place].data=u; e[place].next=head[v]; head[v]=place; e[place].vote=-w; e[place].l=0; e[place].re=place-1;
    }
    void spfa(){
        memset(dis,inf,sizeof(dis));
        memset(use,0,sizeof(use));
        dis[S]=0; use[S]=1; can[S]=inf;
        int pl=1, pr=1; q[1]=S;
        while (pl<=pr){
            int x=q[(pl++)%N];
            for (int ed=head[x]; ed!=0; ed=e[ed].next)
                if (dis[e[ed].data]>dis[x]+e[ed].vote&&e[ed].l!=0){
                    dis[e[ed].data]=dis[x]+e[ed].vote;
                    can[e[ed].data]=min(e[ed].l,can[x]);
                    frm[e[ed].data]=ed;
                    if (use[e[ed].data]==0){
                        use[e[ed].data]=1;
                        q[(++pr)%N]=e[ed].data;
                    }
                }
            use[x]=0;
        }
    }
    void change(){
        ans=ans+(long long)dis[T]*(long long)can[T];
        int now=T;
        while (now!=S){
            e[frm[now]].l-=can[T];
            e[e[frm[now]].re].l+=can[T];
            now=e[e[frm[now]].re].data;
        }
    }
    void flow(){
        for (spfa(); dis[T]!=inf; spfa())
            change();
    }
    int main(){
        m=read(), n=read();
        S=0; T=1; ti=1;
        for (int i=1; i<=n; i++)
            for (int j=1; j<=m; j++){
                mp[j][i]=read();
                pin[j][i]=++ti;
                build(pin[j][i],T,1,0);
            }
        for (int i=1; i<=n; i++){
            p[i]=++ti;
            build(S,p[i],1,0);
            for (int j=1; j<=m; j++)
                for (int k=1; k<=n; k++)
                    build(p[i],pin[j][k],1,mp[j][i]*k);
        }
        flow();
        printf("%.2lf
    ",ans*1.0/n);
        return 0;
    }
    
  • 相关阅读:
    ElasticSearch基本用法
    几款Http小服务器
    【最长上升子序列】HDU 1087——Super Jumping! Jumping! Jumping!
    方差与样本方差、协方差与样本协方差
    方差与样本方差、协方差与样本协方差
    统计推断(statistical inference)
    统计推断(statistical inference)
    R 语言学习(二)—— 向量
    R 语言学习(二)—— 向量
    R 语言的学习(一)
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135990.html
Copyright © 2011-2022 走看看