zoukankan      html  css  js  c++  java
  • LOJ#3097. 「SNOI2019」通信 最小费用流+主席树优化建图

    如果做过软件开发,餐巾计划问题的话这题就秒切了.   

    还是类似的套路:借流思想.   

    正解的话就是无聊地上一个主席树优化建图就行.   

    维护一颗边权为正数地主席树,再维护一颗边权为负数的主席树就行.   

    主席树写了,感觉好恶心......    

    code: 

    #include <bits/stdc++.h>  
    #define N 3008   
    #define inf 1000000000 
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std; 
    int s,t,n,m,flow; 
    ll ans;      
    namespace mcmf      
    {     
        int a[N],flow2[N],inq[N];       
        ll d[N];  
        struct Edge
        {
            int u,v,cap,cost;  
            Edge(int u=0,int v=0,int cap=0,int cost=0):u(u),v(v),cap(cap),cost(cost){}  
        };  
        queue<int>q;     
        vector<int>G[N];
        vector<Edge>edges;      
        inline void add(int u,int v,int cap,int cost) 
        {   
            edges.push_back(Edge(u,v,cap,cost));   
            edges.push_back(Edge(v,u,0,-cost));   
            int p=edges.size();   
            G[u].push_back(p-2);  
            G[v].push_back(p-1);  
        }
        int spfa() 
        {
            for(int i=0;i<N;++i) d[i]=flow2[i]=inf;  
            memset(inq,0,sizeof(inq));   
            d[s]=0,inq[s]=1,q.push(s);         
            while(!q.empty()) 
            {
                int u=q.front(); q.pop(),inq[u]=0;      
                for(int i=0;i<G[u].size();++i) 
                {
                    Edge e=edges[G[u][i]];    
                    if(e.cap>0&&d[e.v]>d[u]+e.cost) 
                    {
                        d[e.v]=d[u]+e.cost;   
                        flow2[e.v]=min(flow2[u],e.cap);    
                        a[e.v]=G[u][i];   
                        if(!inq[e.v]) 
                        {
                            inq[e.v]=1;   
                            q.push(e.v);   
                        }
                    }
                }
            }  
            if(d[t]==inf) return 0;       
            int f=flow2[t];   
            flow+=f;  
            int u=edges[a[t]].u;   
            edges[a[t]].cap-=f;  
            edges[a[t]^1].cap+=f;   
            while(u!=s) 
            {
                edges[a[u]].cap-=f;   
                edges[a[u]^1].cap+=f;   
                u=edges[a[u]].u;      
            }           
            ans+=(ll)d[t]*f;       
            return 1;     
        }
        inline int maxflow() { while(spfa()); return flow; }   
        inline ll getcost() { return ans; }   
    };  
    int I1(int x) { return x; } 
    int I2(int x) { return x+n; }         
    int val[N];  
    int main() 
    {
        // setIO("input");     
        int W; 
        scanf("%d%d",&n,&W);   
        for(int i=1;i<=n;++i)  scanf("%d",&val[i]);      
        s=0,t=(n<<1)+1;
        for(int i=1;i<=n;++i) 
        {
            mcmf::add(s,I1(i),1,0);    
            mcmf::add(I2(i),t,1,0);
            mcmf::add(s,I2(i),1,W);   
        }
        for(int i=1;i<=n;++i) 
        { 
            for(int j=i+1;j<=n;++j) 
            {
                int det=abs(val[i]-val[j]);       
                mcmf::add(I1(i),I2(j),1,det);    // 直接借光  
            }
        }    
        mcmf::maxflow();  
        printf("%lld
    ",mcmf::getcost());   
        return 0; 
    }
    

      

  • 相关阅读:
    IOS中 init和initialize
    UITableView的常用方法
    加载xib文件的两种方式
    openfire修改服务器名称方法
    POST
    ObjectiveC的动态特性
    枚举 UIButton补充
    深入ObjectiveC的动态特性 Runtime
    IOS中 类扩展 xib
    ObjectiveC语法之代码块(block)的使用
  • 原文地址:https://www.cnblogs.com/guangheli/p/12978758.html
Copyright © 2011-2022 走看看