zoukankan      html  css  js  c++  java
  • P3128 [USACO15DEC]最大流Max Flow

    二次联通门 : P3128 [USACO15DEC]最大流Max Flow

    /*
        luogu P3128 最大流Max Flow
        
        说着最大流。。。
        其实跟最大流半毛钱关系没有
        
        是个数据结构题
        
        树剖预处理
        线段树维护区间最大值
        线段树区间修改 
        最后查询以1为根节点的子树中的最大值即可。。
         
    */
    #include <cstdio>
    
    #define Max 50090
    
    inline int max (int a, int b)
    {
        return a > b ? a : b;
    }
    
    inline int min (int a, int b)
    {
        return a < b ? a : b;
    }
    
    inline int swap (int &a, int &b)
    {
        int now = a;
        a = b;
        b = now;
    }
    
    void read (int &now)
    {
        now = 0;
        register char word = getchar ();
        while (word < '0' || word > '9')
            word = getchar ();
        while (word <= '9' && word >= '0')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
    }
    
    class Segment_Tree_Type
    {
        private :
            
            struct Segment_Tree
            {
                int l;
                int r;
                int Mid;
                int Maxn;
                int Ruri;
            }
            
            tree[Max << 4];
            
        public :
            
            void Build (int l, int r, int now)
            {
                tree[now].l = l;
                tree[now].r = r;
                if (l == r)
                    return ;
                tree[now].Mid = (l + r) >> 1;
                Build (l, tree[now].Mid, now << 1);
                Build (tree[now].Mid + 1, r, now << 1 | 1);
            }
            
            void Change_section (int l, int r, int now)
            {
                if (tree[now].l == l && tree[now].r == r)
                {
                    tree[now].Maxn++;
                    tree[now].Ruri++;
                    return ;
                }
                if (tree[now].Ruri)
                {
                    tree[now << 1].Maxn += tree[now].Ruri;
                    tree[now << 1].Ruri += tree[now].Ruri;
                    tree[now << 1 | 1].Maxn += tree[now].Ruri;
                    tree[now << 1 | 1].Ruri += tree[now].Ruri;
                    tree[now].Ruri = 0;
                }
                if (r <= tree[now].Mid)
                    Change_section (l, r, now << 1);
                else if (l > tree[now].Mid)
                    Change_section (l, r, now << 1 | 1);
                else
                {
                    Change_section (l, tree[now].Mid, now << 1);
                    Change_section (tree[now].Mid + 1, r, now << 1 | 1);
                }
                tree[now].Maxn = max (tree[now << 1].Maxn, tree[now << 1 | 1].Maxn);
            }
    
            int Query_section_Maxn (int l, int r, int now)
            {
                if (tree[now].l == l && tree[now].r == r)
                    return tree[now].Maxn;
                if (tree[now].Ruri)
                {
                    tree[now << 1].Maxn += tree[now].Ruri;
                    tree[now << 1].Ruri += tree[now].Ruri;
                    tree[now << 1 | 1].Maxn += tree[now].Ruri;
                    tree[now << 1 | 1].Ruri += tree[now].Ruri;
                    tree[now].Ruri = 0;
                }
                tree[now].Maxn = max (tree[now << 1].Maxn, tree[now << 1 | 1].Maxn);
                if (r <= tree[now].Mid)
                    return Query_section_Maxn (l, r, now << 1);
                else if (l > tree[now].Mid)
                    return Query_section_Maxn (l, r, now << 1 | 1);
                else 
                    return max (Query_section_Maxn (l, tree[now].Mid, now << 1), Query_section_Maxn (tree[now].Mid + 1, r, now << 1 | 1));    
            }    
    };
    
    struct Edge_Type
    {
        
        int Edge_Count;
        
        int edge_list[Max];
        
        struct Edges
        {
            int to;
            int next;
        }
        
        edge[Max << 2];
        
        void Add_Edge (int from, int to)
        {
            Edge_Count++;
            edge[Edge_Count].to = to;
            edge[Edge_Count].next = edge_list[from];
            edge_list[from] = Edge_Count;
            Edge_Count++;
            edge[Edge_Count].to = from;
            edge[Edge_Count].next = edge_list[to];
            edge_list[to] = Edge_Count;
        }
    };
    
    Segment_Tree_Type Tree;
    
    Edge_Type Graph;
    
    class Tree_Chain_Get_Type
    {
        private :
            
            struct Point_Type
            {
                int size;
                int deep;
                int father;
                int up_chain_point;
                int tree_number;
                int end;
            }
            
            point[Max];
            
        public :
            
            int Count;
            
            void Dfs_1 (int now, int father)
            {
                int pos = Count++;
                point[now].father = father;
                point[now].deep = point[father].deep + 1;
                for (int i = Graph.edge_list[now]; i; i = Graph.edge[i].next)
                    if (Graph.edge[i].to != father)
                        Dfs_1 (Graph.edge[i].to, now);
                point[now].size = Count - pos;
            }
            
            void Dfs_2 (int now, int chain)
            {
                int pos = 0;
                point[now].up_chain_point = chain;
                point[now].tree_number = ++Count;
                for (int i = Graph.edge_list[now]; i; i = Graph.edge[i].next)
                    if (!point[Graph.edge[i].to].tree_number && point[Graph.edge[i].to].size > point[pos].size)
                        pos = Graph.edge[i].to;
                if (!pos)
                {
                    point[now].end = Count;
                    return ;
                }
                Dfs_2 (pos, chain);
                for (int i = Graph.edge_list[now]; i; i = Graph.edge[i].next)
                    if (Graph.edge[i].to != pos && !point[Graph.edge[i].to].tree_number)
                        Dfs_2 (Graph.edge[i].to, Graph.edge[i].to);
                point[now].end = Count;
            }
            
            void Change (int x, int y)
            {
                while (point[x].up_chain_point != point[y].up_chain_point)
                {
                    if (point[point[x].up_chain_point].deep < point[point[y].up_chain_point].deep)
                        swap (x, y);
                    Tree.Change_section (point[point[x].up_chain_point].tree_number, point[x].tree_number, 1);
                    x = point[point[x].up_chain_point].father; 
                }
                Tree.Change_section (min (point[x].tree_number, point[y].tree_number), max (point[x].tree_number, point[y].tree_number), 1); 
            }
            
            int Get_Start ()
            {
                return point[1].tree_number;
            }
            
            int Get_End ()
            {
                return point[1].end;
            }
    };
    
    Tree_Chain_Get_Type Make;
     
    int M, N;
    
    int main (int argc, char *argv[])
    {
        read (N);
        read (M);
        int x, y;
        for (int i = 1; i < N; i++)
        {
            read (x);
            read (y);
            Graph.Add_Edge (x, y); 
        }
        Make.Dfs_1 (1, 0);
        Make.Count = 0;
        Make.Dfs_2 (1, 1);
        Tree.Build (1, N, 1);  
        while (M--)
        {
            read (x);
            read (y);
            Make.Change (x, y); 
        }
        printf ("%d", Tree.Query_section_Maxn (Make.Get_Start (), Make.Get_End (), 1));
        return 0;
    }
  • 相关阅读:
    进程与线程
    二维数组和指向指针的指针
    _variant_t 到 CString 转换
    1.15 构造数独
    单链表的一些操作
    C++关键字(2)——extern
    the seventh chapter
    Visual C++ 数据库开发的特点
    CString 和 LPCTSTR区别【转】
    2.5 寻找最大的K个数
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6838064.html
Copyright © 2011-2022 走看看