zoukankan      html  css  js  c++  java
  • bzoj1927: [Sdoi2010]星际竞速 最小费用流

    和软件安装比较相似的拆点模型.   

    我们发现,每个点只能经过一次,也就是说每个点最多可以贡献给其他点一次.   

    然后连边方式和软件安装就几乎是相同的了.  

    code: 

    #include <bits/stdc++.h>  
    #define N 2008   
    #define inf 10000000 
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std; 
    int s,t,n,m,flow,ans;      
    namespace mcmf      
    {     
        int d[N],a[N],flow2[N],inq[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+=d[t]*f;   
            return 1;     
        }
        inline int maxflow() { while(spfa()); return flow; }   
        inline int getcost() { return ans; }   
    };  
    int tim[N];  
    int I1(int x) { return x; }   
    int I2(int x) { return x+n; }    
    int main() 
    { 
        // setIO("input");     
        scanf("%d%d",&n,&m);   
        for(int i=1;i<=n;++i) scanf("%d",&tim[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,tim[i]);             
                                 
        }
        for(int i=1;i<=m;++i) 
        {
            int u,v,w;  
            scanf("%d%d%d",&u,&v,&w);   
            if(u>v) swap(u,v);  
            mcmf::add(I1(u),I2(v),1,w);    
        }
        mcmf::maxflow();  
        printf("%d
    ",mcmf::getcost());  
        return 0;  
    }
    

      

  • 相关阅读:
    PHP去除所有的空格
    PHP学习之分页类
    PHP学习之验证码类
    PHP学习之迭代生成器
    PHP学习之PHP trait解析
    PHP学习之PHP代码的优化
    PHP学习之PHP的语法糖
    PHP学习之PHP编码习惯
    PHP介绍
    Centos7安装PHP、安装MySQL、安装apache
  • 原文地址:https://www.cnblogs.com/guangheli/p/12978260.html
Copyright © 2011-2022 走看看