zoukankan      html  css  js  c++  java
  • BZOJ2286/Luogu2495 [Sdoi2011]消耗战 (虚树)

    // never forget open "Head.cpp", boy, never !
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define R(a,b,c) for(register int  a = (b); a <= (c); ++ a)
    #define nR(a,b,c) for(register int  a = (b); a >= (c); -- a)
    #define Max(a,b) ((a) > (b) ? (a) : (b))
    #define Min(a,b) ((a) < (b) ? (a) : (b))
    #define Fill(a,b) memset(a, b, sizeof(a))
    #define Swap(a,b) a^=b^=a^=b
    #define ll long long
    #define ON_DEBUG
    
    #ifdef ON_DEBUG
    
    #define D_e_Line printf("
    
    ----------
    
    ")
    #define D_e(x)  cout << #x << " = " << x << endl
    #define Pause() system("pause")
    
    #else
    
    #define D_e_Line ;
    
    #endif
    
    struct ios{
        template<typename ATP>ios& operator >> (ATP &x){
            x = 0; int f = 1; char c;
            for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-')  f = -1;
            while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
            x*= f;
            return *this;
        }
    }io;
    using namespace std;
    #include <vector>
    
    const int N = 250007;
    
    int n;
    
    namespace EdgeStar{
    
    struct Edge{
        int nxt, pre, w;
    }e[N << 1];
    int head[N], cntEdge;
    inline void add(int u, int v, int w){
        e[++cntEdge] = (Edge){head[u], v, w}, head[u] = cntEdge;
    }
    
    }
    using namespace EdgeStar;
    
    long long minn[N];
    
    namespace TreeChainParticipation{
        
    int siz[N], son[N], fa[N], dep[N];
    inline void DFS_First(int u, int father){
        fa[u] = father, dep[u] = dep[father] + 1, siz[u] = 1;
        for(register int i = head[u]; i; i = e[i].nxt){
            int v = e[i].pre;
            if(v == father) continue;
            minn[v] = Min(minn[u], e[i].w);
            DFS_First(v, u);
            
            siz[u] += siz[v];
            if(!son[u] || siz[v] > siz[son[u]]){
                son[u] = v;
            }
        }
        
    }
    int top[N], dfn[N], dfnIdx;
    inline void DFS_Second(int u, int ancester){
        top[u] = ancester, dfn[u] = ++dfnIdx;
        if(!son[u]) return;
        DFS_Second(son[u], ancester);
        for(register int i = head[u]; i; i = e[i].nxt){
            int v = e[i].pre;
            if(v != fa[u] && v != son[u]){
                DFS_Second(v, v);
            }
        }
    }
    inline int LCA(int x, int y){
        while(top[x] != top[y]){
            if(dep[top[x]] < dep[top[y]]) Swap(x, y);
            x = fa[top[x]];
        }
        return dep[x] < dep[y] ? x : y;
    }
    
    }
    using namespace TreeChainParticipation;
    
    int sta[N], _top;
    vector<int> G[N];
    
    //Vitual Tree
    inline void Insert(int x){
        if(_top == 1){
            sta[++_top] = x;
            return;
        }
        int lca = LCA(x, sta[_top]);
        if(lca == sta[_top]){
        	//G[sta[_top]].push_back(x);
        	//sta[++_top] = x;
        	return;
        }
        while(_top > 1 && dfn[sta[_top - 1]] >= dfn[lca]){
            G[sta[_top - 1]].push_back(sta[_top]);
            --_top;
        }
        // maybe it's not need in this problem // or maybe need ? // shit, of course ! Who said the node 1 should be root
        if(lca != sta[_top]){
            G[lca].push_back(sta[_top]);
            sta[_top] = lca;
        }
        sta[++_top] = x;
    }
    
    inline long long DFS(int u){
        if(G[u].size() == 0) return minn[u];
        long long sum = 0;
        for(vector<int>::iterator v = G[u].begin(); v != G[u].end(); ++v){
            sum += DFS(*v);
        }
        G[u].clear();
        return Min(sum, minn[u]);
    }
    
    int act[N];
    
    inline int cmp(const int &a, const int &b){
        return dfn[a] < dfn[b];
    }
    
    int main(){
    
        io >> n;
        R(i,2,n){
            int u, v, w;
            io >> u >> v >> w;
            add(u, v, w);
            add(v, u, w);
        }
        
        minn[1] = 9223372036854775807;
        
        DFS_First(1, 0);
        DFS_Second(1, 1);
        
        int Tasks;
        io >> Tasks;
        while(Tasks--){
            int m;
            io >> m;
            R(i,1,m){
                io >> act[i];
            }
            sort(act + 1, act + m + 1, cmp); // important !
            _top = 1;
            sta[_top] = 1;
            R(i,1,m){
                 Insert(act[i]);
            }
            while(_top){
                G[sta[_top - 1]].push_back(sta[_top]);
                --_top;
            }
            
            printf("%lld
    ", DFS(1));
        }
        
        return 0;
    }
    
    /*
    10
    1 5 13
    1 9 6
    2 1 19
    2 4 8
    2 3 91
    5 6 8
    7 5 4
    7 8 31
    10 7 9
    3
    2 10 6
    4 5 7 8 3
    3 9 4 6
    
    */
    

  • 相关阅读:
    记账本第二天
    记账本第一天
    HDU 1811
    Codeforces Round #246 (Div. 2) D. Prefixes and Suffixes
    KMP超强模板贴一份
    2014辽宁省赛总结
    Codeforces Round #244 (Div. 2)
    CodeForces 383D Antimatter
    NEU 1351 Goagain and xiaodao's romantic story I
    UVA 10692 Huge Mod
  • 原文地址:https://www.cnblogs.com/bingoyes/p/11213687.html
Copyright © 2011-2022 走看看