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

    思路

    这个题哪里有那么费脑筋
    我们可以树链剖分嘛LCT昨天学的时候睡着了,不是太会
    两遍dfs+一个5行的BIT
    其实树链剖分学好了对倍增和LCT理解上都有好处
    一条路径上的修改
    由于一条剖出来的链是连续的,我们要选择数据结构维护
    不过这里不用维护太多东西,只是区间+1
    我们可以选择常数小,好写的树状数组(从50行的线段树变成5行的
    BIT)
    而且使得(O(nlog_{2}))的算法跑的并不慢
    具体就是用差分思想,修改区间[L,R]时
    $[1,R] +1 $ ([1,L-1] -1)达到修改的目的
    最后查询时
    直接每次查询[1,i]的值就可得到i的最终压力值

    代码

    #include <bits/stdc++.h>
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int maxn=2e5+7;
    int read() {
        int x=0,f=1;char s=getchar();
        for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
        for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
        return x*f;
    }
    vector<int> G[maxn];
    int n,m,top[maxn],f[maxn],siz[maxn],idx[maxn],cnt,son[maxn],dep[maxn];
    void dfs1(int u,int fa) {
        f[u]=fa;
        siz[u]=1;
        dep[u]=dep[fa]+1;
        for(vector<int>::iterator it=G[u].begin();it!=G[u].end();++it) {
            if(*it==fa) continue;
            dfs1(*it,u);
            siz[u]+=siz[*it];
            if(siz[son[u]] < siz[*it]) son[u]=*it;
        }
    }
    void dfs2(int u,int topf) {
        idx[u]=++cnt;
        top[u]=topf;
        if(!son[u]) return;
        dfs2(son[u],topf);
        for(std::vector<int>::iterator it=G[u].begin();it!=G[u].end();++it)
            if(!idx[*it]) dfs2(*it,*it);
    }
    namespace BIT {
        int sum[maxn];
        int lowbit(int x) {return x&-x;}
        void add(int x,int k) {for(int i=x;i<=n;i+=lowbit(i)) sum[i]+=k;}
        int query(int x) {int ans=0;for(int i=x;i>=1;i-=lowbit(i)) ans+=sum[i];return ans;}
        void modify(int x,int y) {if(x!=n)add(y+1,-1);add(x,1);}
    }
    void change(int x,int y) {
        while(top[x]!=top[y]) {
            if(dep[top[x]] < dep[top[y]]) swap(x,y);
            BIT::modify(idx[top[x]],idx[x]);
            x=f[top[x]];
        }
        if(dep[x] > dep[y]) swap(x,y);
        BIT::modify(idx[x],idx[y]);
    }
    int main() {
        n=read(),m=read();
        FOR(i,2,n) {
            int x=read(),y=read();
            G[x].push_back(y),G[y].push_back(x);
        }
        dfs1(1,0);dfs2(1,1);
        FOR(i,1,m) change(read(),read());
        int ans=0;
        FOR(i,1,n) ans=max(ans,BIT::query(i));
        cout<<ans<<"
    ";
        return 0;
    }
    
  • 相关阅读:
    C#操作Redis Set 无序集合
    C#操作Redis Hash数据表
    C#操作Redis List 列表
    C#操作Redis String字符串
    Redis 小结
    建造者模式
    外观模式
    模板方法模式
    原型模式
    select ie6 的bug 层级
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10181350.html
Copyright © 2011-2022 走看看