• 洛谷 P2495 [SDOI2011]消耗战


    题目描述

    在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。

    侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。

    输入输出格式

    输入格式:

    第一行一个整数n,代表岛屿数量。

    接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。

    第n+1行,一个整数m,代表敌方机器能使用的次数。

    接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。

    输出格式:

    输出有m行,分别代表每次任务的最小代价。

    输入输出样例

    输入样例#1:
    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
    
    输出样例#1:
    12
    32
    22
    

    说明

    【数据规模和约定】

    对于10%的数据,2<=n<=10,1<=m<=5,1<=ki<=n-1

    对于20%的数据,2<=n<=100,1<=m<=100,1<=ki<=min(10,n-1)

    对于40%的数据,2<=n<=1000,m>=1,sigma(ki)<=500000,1<=ki<=min(15,n-1)

    对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1

    这题没A,先放着,mlog^2n跑这个数据卡不过去

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <map>
    #include <stack>
    #include <set>
    #include <vector>
    #include <queue>
    #include <time.h>
    #define eps 1e-7
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    #define rep0(j,n) for(int j=0;j<n;++j)
    #define rep1(j,n) for(int j=1;j<=n;++j)
    #define pb push_back
    #define set0(n) memset(n,0,sizeof(n))
    #define ll long long
    #define ull unsigned long long
    #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    #define print_runtime printf("Running time:%.3lfs
    ",double(clock())/1000.0)
    #define TO(j) printf(#j": %d
    ",j);
    //#define OJ
    using namespace std;
    const int MAXINT = 250010;
    const int MAXNODE = 100010;
    const int MAXEDGE = 2 * MAXNODE;
    char BUF[30000000], *buf;
    int read() {
        int x = 0;
        while (!isdigit(*buf)) buf++;
        while (isdigit(*buf)) { x = x * 10 + *buf++ - '0';}
        return x;
    }
    //------------------- Head Files ----------------------//
    int toid[MAXINT];
    struct res {
        int v, p;
        res(int _v, int _p) : v(_v), p(_p) {}
        res() {}
    };
    
    res add(res a, res b) {
        return (a.v < b.v ? a : b);
    }
    struct node {
        int lb, rb;
        node *l, *r;
        res ans, org;
        int del, cv, rec;
        inline void recover() __attribute__((optimize("-O2"))){
            del = 0;
            cv = INF;
            ans = org;
            rec = 1;
        }
        inline void cover(int c) __attribute__((optimize("-O2"))){
            cv = ans.v = c;
            if (del) del = 0;
        }
        inline void dec(int c) __attribute__((optimize("-O2"))){
            del += c;
            ans.v -= c;
        }
        inline void pushdown() __attribute__((optimize("-O2"))){
            if (rec) {
                l->recover(); r->recover();
                rec = 0;
            }
            if (cv != INF) {
                l->cover(cv); r->cover(cv);
                cv = INF;
            }
            if (del != 0) {
                l->dec(del);
                r->dec(del);
                del = 0;
            }
        }
        inline void pushup() __attribute__((optimize("-O2"))){
            ans = add(l->ans, r->ans);
        }
        node() {
            ans.v = del = cv = INF;
            rec = 0;
        }
    };
    int n, m, fa[MAXINT], sz[MAXINT], top[MAXINT], dfn[MAXINT], cnt_dfn = 1, dep[MAXINT], cnt, va[MAXINT], val[MAXINT], dfne[MAXINT];
    struct SegTree {
        node mp[MAXINT * 4];
        node *root;
        int _cnt;
        SegTree() {
            _cnt = 0;
        }
        inline node *newnode(int l, int r) __attribute__((optimize("-O2"))){
            node *p = &mp[_cnt++];
            p->lb = l;
            p->rb = r;
            return p;
        }
        inline void maketree(int lb, int rb, node *&p) __attribute__((optimize("-O2"))){
            p = newnode(lb, rb);
            if (rb - lb > 1) {
                maketree(lb, (lb + rb) / 2, p->l);
                maketree((lb + rb) / 2, rb, p->r);
                p->pushup();
            }
            else {
                p->ans.v = val[p->lb];
                p->ans.p = lb;
            }
            p->org = p->ans;
        }
        inline void del(int lb, int rb, int c) __attribute__((optimize("-O2"))){
            del(lb, rb, c, root);
        }
        inline void del(int lb, int rb, int c, node *p) __attribute__((optimize("-O2"))){
            if (lb >= p->rb || rb <= p->lb) return;
            if (lb <= p->lb && rb >= p->rb) { p->dec(c); return; }
            p->pushdown();
            del(lb, rb, c, p->l);
            del(lb, rb, c, p->r);
            p->pushup();
        }
        inline void cover(int lb, int rb) __attribute__((optimize("-O2"))){
            cover(lb, rb, root);
        }
        inline void cover(int lb, int rb, node *p) __attribute__((optimize("-O2"))){
            if (lb >= p->rb || rb <= p->lb) return;
            if (lb <= p->lb && rb >= p->rb) { p->cover(0); return; }
            p->pushdown();
            cover(lb, rb, p->l);
            cover(lb, rb, p->r);
            p->pushup();
        }
        inline res query(int lb, int rb) __attribute__((optimize("-O2"))){
            return query(lb, rb, root);
        }
        inline res query(int lb, int rb, node *p) __attribute__((optimize("-O2"))){
            if (lb >= p->rb || rb <= p->lb) return res(INF, INF);
            if (lb <= p->lb && rb >= p->rb) return p->ans;
            p->pushdown();
            return add(query(lb, rb, p->l), query(lb, rb, p->r));
        }
        inline void recover() __attribute__((optimize("-O2"))){
            root->recover();
        }
    } st;
    
    struct edge {
        int u, v, l;
        edge *nxt;
        edge() {}
        edge(int _u, int _v, int _l, edge *_nxt) : u(_u), v(_v), l(_l), nxt(_nxt) {}
    } mp[MAXINT * 2], *head[MAXINT];
    inline void addedge(int u, int v, int l) {
        mp[cnt] = edge(u, v, l, head[u]);
        head[u] = &mp[cnt++];
        mp[cnt] = edge(v, u, l, head[v]);
        head[v] = &mp[cnt++];
    }
    inline void dfs1(int p) {
        sz[p] = 1;
        iter(i, p) {
            if (i->v == fa[p])continue;
            fa[i->v] = p; dep[i->v] = dep[p] + 1; va[i->v] = i->l;
            dfs1(i->v);
            sz[p] += sz[i->v];
        }
    }
    inline void dfs2(int p) {
        int mx = 0, gs = 0;
        dfn[p] = cnt_dfn++;
        iter(i, p) {
            if (i->v == fa[p]) continue;
            if (sz[i->v] > mx) {
                mx = sz[i->v];
                gs = i->v;
            }
        }
        if (gs == 0) return;
        top[gs] = top[p];
        dfs2(gs);
        iter(i, p) {
            if (i->v == fa[p] || i->v == gs) continue;
            top[i->v] = i->v;
            dfs2(i->v);
        }
        dfne[p] = cnt_dfn;
    }
    inline void modify(int l, int r, int c) {
        while (top[l] != top[r]) {
            if (dep[top[l]] > dep[top[r]]) {
                st.del(dfn[top[l]], dfn[l] + 1, c, st.root);
                l = fa[top[l]];
            }
            else {
                st.del(dfn[top[r]], dfn[r] + 1, c, st.root);
                r = fa[top[r]];
            }
        }
        st.del(min(dfn[r], dfn[l]), max(dfn[r], dfn[l]) + 1, c, st.root);
    }
    inline void cover(int p) {
        st.cover(dfn[p], dfne[p]);
    }
    inline res query(int l, int r) {
        res ans(INF, INF);
        while (top[l] != top[r]) {
            if (dep[top[l]] > dep[top[r]]) {
                ans = add(st.query(dfn[top[l]], dfn[l] + 1), ans);
                l = fa[top[l]];
            }
            else {
                ans = add(st.query(dfn[top[r]], dfn[r] + 1), ans);
                r = fa[top[r]];
            }
        }
        ans = add(st.query(min(dfn[r], dfn[l]), max(dfn[r], dfn[l]) + 1), ans);
        return ans;
    }
    inline void get_input() __attribute__((optimize("-O2")));
    inline void work() __attribute__((optimize("-O2")));
    int main() {
        get_input();
        work();
        return 0;
    }
    inline void work() {
        dfs1(1);
        dfs2(1);
        rep1(i, n) val[dfn[i]] = va[i];
        rep1(i, n) toid[dfn[i]] = i;
        val[1] = INF;
        st.maketree(1, n + 1, st.root);
        while (m--) {
            st.recover();
            int k = read();
            ll ans = 0;
            while (k--) {
                int p = read();
                res ret = query(1, p);
                ans += ret.v;
                cover(toid[ret.p]);
                modify(1, fa[toid[ret.p]], ret.v);
            }
            printf("%lld
    ", ans);
        }
    }
    inline void get_input() {
        BUF[fread(BUF, 1, 30000000, stdin)] = '';
        buf = BUF;
        n = read();
        rep0(i, n - 1) {
            int u = read(), v = read(), l = read();
            addedge(u, v, l);
        }
        m = read();
    }
    /*
    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
    1
    4 5 7 8 3
    */
  • 相关阅读:
    block、inline、inline-block
    js 的复制和引用 (传值和传址)
    俄罗斯方块和作品集
    js 连续赋值。。理解不了,先占坑
    8.7 jquery-dom manipulation
    08.04 对象构造方法
    对象的基本操作
    08.03 js _oop
    08.02 对象
    The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
  • 原文地址:https://www.cnblogs.com/LoveYayoi/p/6917904.html
Copyright © 2020-2023  润新知