zoukankan      html  css  js  c++  java
  • GDKOI2014 石油储备计划

    Description

     

    Input

    Output

    对于每组数据,输出一个整数,表示达到“平衡”状态所需的最小代价。
     

    Sample Input

    2

    3

    6 1 5

    1 2 1

    2 3 2

    5

    4 5 4 3 2

    1 3 1

    1 2 2

    2 4 3

    2 5 4

    Sample Output

    4

    4

    样例解释:

    对于第一组数据,从城市1到城市2运输2桶石油,代价为1*2=2;从城市3往城市2运输1桶石油,代价为2*1=2。此时三个城市储备量都为4桶,该状态的平衡度为0。

    对于第二组数据,从城市2到城市5运输1桶石油,代价为1*4=4;此时五个城市储备量为(4,4,4,3,3),该状态的非平衡度为1.2,是能达到的所有状态的最小值。
     

    Data Constraint

    对于20%的数据,N<=15

    对于100%的数据,T<=10,N<=100,0<=si<=10000,1<=X,Y<=N,1<=Z<=10000。
     
    首先容易得到结论:达到平衡状态时,每个点的油量要么为(sum/n),要么为(sum/n)+1,现在每个点有一个初始容量,在树上相邻的点可以转移石油。
    我们可以据此建模
     
    对于s向每个点,连一条上下界均为初始量的边,费用为0,表示最初容量,
    对于每个点向t,连一条下界为(sum/n),上界为(sum/n)+1的边,表示经转移后的容量
    对于原树上相邻的点,连一条下界为0,上界为正无穷,费用为距离的边,表示转移可用的路径
     
    然后跑一遍最小费用可行流即可
     
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    typedef long long ll;
    
    int g[2001],next[2011],y[2011],cost[2011],flow[2011];
    int que[2000011],dis[2011],lb[2011],mn[2011],vis[2011];
    int du[2011],a[2011];
    int tt,tl,n,i,s,t,S,T,x,z,q,sum,dt,tj;
    ll ans;
    
    void star(int i,int j,int k,int l)
    {
        tt++;
        next[tt]=g[i];
        g[i]=tt;
        y[tt]=j;
        flow[tt]=k;
        cost[tt]=l;
        tt++;
        next[tt]=g[j];
        g[j]=tt;
        y[tt]=i;
        flow[tt]=0;
        cost[tt]=-l;
    }
    
    void Spfa()//记录dis(最短路),min(最小流量),lb(连过的边,退流用)
    {
        int l,r,x,j,k;
        memset(dis,127,sizeof(dis));
        memset(mn,0,sizeof(mn));
        memset(lb,0,sizeof(lb));
        tl++;
        l=r=1;
        que[l]=S;
        dis[S]=0;mn[S]=21474836;
        vis[S]=tl;
        while(l<=r){
            x=que[l];
            j=g[x];
            while(j!=0){
                if(flow[j]>0){
                    k=y[j];
                    if(dis[x]+cost[j]<dis[k]){
                        dis[k]=dis[x]+cost[j];
                        if(mn[x]<flow[j])mn[k]=mn[x];
                        else mn[k]=flow[j];
                        lb[k]=j;
                        if(vis[k]!=tl){
                            r++;
                            que[r]=k;
                            vis[k]=tl;
                        }
                    }
                }
                j=next[j];
            }
            l++;
            vis[x]--;
        }
    }
    
    void Minflow()
    {
        int x,j;
        ans=0;
        while(true){
            Spfa();
            if(dis[T]==2139062143)break;
            ans+=(ll)mn[T]*dis[T];
            x=T;
            while(x!=S){
                j=lb[x];
                flow[j]-=mn[T];
                flow[j^1]+=mn[T];
                x=y[j^1];
            }
        }
    }
    
    int main()
    {
        scanf("%d",&dt);
        for(tj=1;tj<=dt;tj++){
            tt=1;
            memset(g,0,sizeof(g));
            memset(du,0,sizeof(du));
            scanf("%d",&n);
            sum=0;
            s=n+1;t=n+2;S=n+3;T=n+4;
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
                du[i]+=a[i];
                du[s]-=a[i];
                sum+=a[i];
            }
            for(i=1;i<=n;i++){
                du[i]-=(sum/n);
                du[t]+=(sum/n);
                star(i,t,1,0);
            }
            for(i=1;i<n;i++){
                scanf("%d%d%d",&x,&z,&q);
                star(x,z,21474836,q);
                star(z,x,21474836,q);
            }
            star(t,s,21474836,0);
            for(i=1;i<=t;i++){
                if(du[i]>0)star(S,i,du[i],0);
                else star(i,T,-du[i],0);
            }
            Minflow();
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    遥感影像数据产品级别概述
    数据传输中的成帧
    帧同步
    I、Q信号是如何产生的,I、Q信号复用的作用
    调制解调技术
    基带信号、载波信号和宽带信号
    浅谈MVP架构及开发模式
    剑指offer代码 vs2013执行
    进程的状态
    死锁的必要条件及避免
  • 原文地址:https://www.cnblogs.com/applejxt/p/4483831.html
Copyright © 2011-2022 走看看