穹妹的家

In solitude , where we are least alone.

[虚树dp] bzoj2286: Sdoi2011消耗战

Sdoi2011消耗战

题解：

#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+5;
typedef long long ll;
typedef pair<int,ll> edg;
const ll inf = ~0ull>>5;
vector<edg>G[N];
vector<int>qry, GG[N];
ll cost[N];
int dep[N], fa[N][25], in[N], cnt = 0;
int st[N], top;
bool vis[N];
inline bool cmp(const int& a, const int& b){
return in[a] < in[b];
}
void dfs1(int rt, int f){
in[rt] = ++cnt;
for(int i = 1; i < 25; ++i){
if(dep[rt] < (1<<i)) break;
fa[rt][i] = fa[fa[rt][i-1]][i-1];
}
for(int i = 0; i < G[rt].size(); ++i){
int v = G[rt][i].first;
if(v == f) continue;
cost[v] = min(cost[rt], G[rt][i].second);
dep[v] = dep[rt]+1;
fa[v][0] = rt;
dfs1(v, rt);
}
}
int lca(int a, int b){
if(dep[a] < dep[b]) swap(a, b);
int delt = dep[a] - dep[b];
for(int i = 0; i < 25; ++i){
if(delt&(1<<i)) a = fa[a][i];
}
for(int i = 24; i >= 0; --i){
if(fa[a][i] != fa[b][i]) a = fa[a][i], b = fa[b][i];
}
if(a != b) return fa[a][0];
else return a;
}
if(a == b) return;
GG[a].push_back(b);
}
ll dp[N];
void solve(int rt){
dp[rt] = cost[rt];
if(!vis[rt]){
ll sum = 0;
for(int i = 0; i < GG[rt].size(); ++i){
solve(GG[rt][i]);
sum += dp[GG[rt][i]];
}
dp[rt] = min(dp[rt], sum);
}
}
int main(){
int n;
scanf("%d", &n);
for(int a, b, c, i = 1; i < n; ++i){
scanf("%d%d%d", &a, &b, &c);
G[a].push_back(edg(b, c));
G[b].push_back(edg(a, c));
}
cost[1] = inf;
dfs1(1, 1);
int q;
scanf("%d", &q);
while(q--){
qry.clear();
int k;
scanf("%d", &k);
for(int a, i = 0; i < k; ++i){
scanf("%d", &a);
qry.push_back(a);
vis[a] = 1;
}
sort(qry.begin(), qry.end(), cmp);
int len = qry.size();
for(int i = 1; i < len; ++i){
qry.push_back(lca(qry[i], qry[i-1]));
}
qry.push_back(1);
sort(qry.begin(), qry.end(), cmp);
qry.erase(unique(qry.begin(), qry.end()), qry.end());
int top = 0;
for(int i = 0; i < qry.size(); ++i){
while(top > 0 && lca(st[top], qry[i]) != st[top]) top--;
st[++top] = qry[i];
}
solve(1);
for(int i = 0; i < qry.size(); ++i) GG[qry[i]].clear(), vis[qry[i]] = 0;
printf("%lld\n", dp[1]);
}
}

03-01 57

03-06 1780

01-09 1876

12-23 893

03-01 915

01-19 494

11-26 145

03-01 142

09-06 123

08-25 560