zoukankan      html  css  js  c++  java
  • LibreOJ #102. 最小费用流

    二次联通门 : LibreOJ #102. 最小费用流

    /*
        LibreOJ #102. 最小费用流
        
        Spfa跑花费 
        记录路径
        倒推回去
         
    */
    #include <cstring>
    #include <cstdio>
    #include <queue>
    
    #define Max 10000
    
    void read (int &now)
    {
        now = 0;
        register char word = getchar ();
        while (word > '9' || word < '0')
            word = getchar ();
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
    }
    
    inline int min (int a, int b)
    {
        return a < b ? a : b;
    }
    
    class Cost_Flow_Type
    {
        
        private :
            
            int __to[Max * 70];
            int __next[Max * 70];
            int __flow[Max * 70], __cost[Max * 70];
            
            int edge_list[Max];
            int Edge_Count;
            
            int dis[Max], can_flow[Max];
            bool visit[Max];
            int pre[Max];
            
        public :
            
            Cost_Flow_Type ()
            {
                Edge_Count = 1;
            }
            
            inline void Insert_edge (int from, int to, int flow, int cost)
            {
                Edge_Count ++;
                
                __to[Edge_Count] = to;
                __next[Edge_Count] = edge_list[from];
                edge_list[from] = Edge_Count;
                
                __flow[Edge_Count] = flow;
                __cost[Edge_Count] = cost;
                
                Edge_Count ++;
                
                __to[Edge_Count] = from;
                __next[Edge_Count] = edge_list[to];
                edge_list[to] = Edge_Count;
                
                __flow[Edge_Count] = 0;
                __cost[Edge_Count] = -cost;
            }
            
            bool Spfa (int Start, int End)
            {
                memset (dis, 0x3f, sizeof dis);
                memset (visit, false, sizeof visit);
                
                std :: queue <int> Queue;
                register int now;
                
                visit[Start] = true;
                can_flow[Start] = dis[0];
                pre[Start] = 0;
                
                for (Queue.push (Start), dis[Start] = 0; !Queue.empty (); Queue.pop ())
                {
                    now = Queue.front ();
                    
                    visit[now] = false;
                    
                    for (int i = edge_list[now]; i; i = __next[i])
                        if (__flow[i] && dis[__to[i]] > dis[now] + __cost[i])
                        {
                            dis[__to[i]] = dis[now] + __cost[i];
                            pre[__to[i]] = i;
                            
                            can_flow[__to[i]] = min (can_flow[now], __flow[i]);
                            
                            if (!visit[__to[i]])
                            {
                                Queue.push (__to[i]);
                                visit[__to[i]] = true; 
                            }
                        }
                }
                
                return dis[End] < dis[0];
            }
            
            void Get_Cost_Flow (int Start, int End)
            {
                int res = 0;
                int Cost_ = 0;
                for (int x; Spfa (Start, End); )
                {
                    x = can_flow[End];
                    for (int i = End; i != Start; i = __to[pre[i] ^ 1])
                    {
                        __flow[pre[i]] -= x;
                        __flow[pre[i] ^ 1] += x;
                    }
                    res += x;
                    Cost_ += dis[End] * x;
                }
                
                printf ("%d %d", res, Cost_);
            }
    };
    
    int N, M;
    
    Cost_Flow_Type Make;
    
    int main (int argc, char *argv[])
    {
        int x, y, z, Flandre;
        
        for (read (N), read (M); M --; )
        {
            read (x);
            read (y);
            read (z);
            read (Flandre);
            
            Make.Insert_edge (x, y, z, Flandre); 
        }
        
        Make.Get_Cost_Flow (1, N);
        
        return 0;
    }
  • 相关阅读:
    C#基础:单例模式与多线程
    C#基础:线程同步
    C#基础:C#中的数据结构
    C#基础:GC中什么是代,一共分几代
    C#基础:Dispose方法和Finalize方法在何时被调用
    C#基础:.NET中GC的运行机制
    C#基础:简述.NET中堆栈和堆的特点和差异
    PLSQL_基础系列05_视图控制WITH CHECK OPTION(案例)
    PLSQL_基础系列04_时间间隔INTERVAL(案例)
    PLSQL_基础系列03_合并操作UNION / UNION ALL / MINUS / INTERSET(案例)
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7076352.html
Copyright © 2011-2022 走看看