1. 程式人生 > >洛谷 P2495 [SDOI2011]消耗戰

洛谷 P2495 [SDOI2011]消耗戰

+= sdi line 分布 即使 == signed -o iostream

題目描述

在一場戰爭中,戰場由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\n",double(clock())/1000.0)
#define TO(j) printf(#j": %d\n",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\n", ans);
    }
}
inline void get_input() {
    BUF[fread(BUF, 1, 30000000, stdin)] = \0;
    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
*/

洛谷 P2495 [SDOI2011]消耗戰