zoukankan      html  css  js  c++  java
  • HDU 6634 网络流最小割模型 启发式合并

    如果我们先手拿完所有苹果再去考虑花费的话。

    S -> 摄像头 -> 苹果 -> T

    就相当于找到一个最小割使得S和T分开。

    ans = sum - flow。

    然后对于这一个模型, 我们可以不用网络流去解决。

    我们从叶子出发,然后从下往上合并。

    每次到一个节点的时候,我们先把摄像机所对应的影响去除。

    然后把这个点的剩下流量传给父亲。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    const int N = 3e5 +100;
    //vector<int> vc[N];
    vector<pll> camera[N];
    map<int, LL> mp[N];
    map<int, LL>::iterator it;
    int deep[N];
    int a[N], f[N];
    LL sum;
    void Merge(map<int, LL> & m1, map<int, LL> & m2){
        if(m1.size() < m2.size()){
            m1.swap(m2);
        }
        for(auto & it : m2){
            m1[it.fi] += it.se;
        }
    }
    map<int,int> mp1, mp2;
    int main(){
        int T, n, m;
        scanf("%d", &T);
        deep[1] = 1;
        while(T--){
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n; ++i) mp[i].clear(), camera[i].clear();
            for(int i = 2; i <= n; ++i){
                scanf("%d", &f[i]);
                deep[i] = deep[f[i]] + 1;
            }
            sum = 0;
            for(int i = 1; i <= n; ++i){
                scanf("%d", &a[i]);
                sum += a[i];
            }
            for(int i = 1, x, k, c; i <= m; ++i){
                scanf("%d%d%d", &x, &k, &c);
                camera[x].pb({k, c});
            }
            for(int i = n; i >= 1; --i){
                mp[i][-deep[i]] += a[i];
                for(auto & t : camera[i]){
                    it = mp[i].lower_bound(-(deep[i]+t.fi));
                    while(it != mp[i].end()){
                        if(t.se < (it->se)){
                            sum -= t.se;
                            it -> se -= t.se;
                            t.se = 0;
                            break;
                        }
                        else {
                            sum -= it->se;
                            t.se -= it->se;
                            it = mp[i].erase(it);
                        }
                    }
                }
                if(f[i]) Merge(mp[f[i]], mp[i]);
            }
            printf("%lld
    ", sum);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    redis的数据类型与应用场景(二)
    redis的安装与配置(一)
    Spring Security教程 ---- 验证码功能的实现
    Java类文件结构
    实体字符
    前端安全之XSS攻击
    $_SERVER[]数组解析
    php主要用于哪几方面
    集群与分布式概念
    python操作mongodb实例
  • 原文地址:https://www.cnblogs.com/MingSD/p/11345396.html
Copyright © 2011-2022 走看看