[SDOI2011]消耗战

[SDOI2011]消耗战

题意:

给出n个点的一棵带有边权的树,以及q个询问.每次询问给出k个点,询问这使得这k个点与1点不连通所需切断的边的边权和最小是多少.

题解:

树型dp+虚树
dp[x]:切断x及其子树上询问点的最小代价
预处理出minv[pos]代表从11到pos路径上最小的边权
如果pos是询问点,dp(pos)=minv[pos]
否则,最小代价dp(pos)=min(minv[pos],∑dp(to))(其中to是pos的儿子)
如果pos为询问点,按理说不用dp[to]的值,但是仍然要对其儿子进行dfs,因为清空虚树需要对整个虚树进行遍历
如果对整个子树进行dp,复杂度过高,这时候就需要建虚树,(关于虚树见博文)
建虚图:

void insert(int x) {if(top == 1) {s[++top] = x; return ;}int lca = LCA(x, s[top]);if(lca == s[top]) return ;//以为s[top]也是关键点,那么s[top]子树里的点就没必要处理了 while(top > 1 && dfn[s[top - 1]] >= dfn[lca]) add_edge(s[top - 1], s[top]), top--;if(lca != s[top]) add_edge(lca, s[top]), s[top] = lca;//s[++top] = x;
}

为什么(lca == s[top]直接推出不把x加栈内
因为s[top]也是关键点,x也是关键点,x是s[top]的子树,那根据题意如果将s[top]与根节点断开,x节点自然也就断开了,也就是我们只需要考虑s[top]即可(x自动被考虑其中)

代码:

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#define LL long long
char buf[(1 << 21) + 1], *p1 = buf, *p2 = buf;
using namespace std;
const int MAXN = 250001;
inline int read() {char c = getchar(); int x = 0, f = 1;while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();return x * f;
}
char obuf[1 << 24], *O=obuf;
void print(LL x) {if(x > 9) print(x / 10);*O++= x % 10 + '0';
}
int N, M;
struct Edge {int u, v, w, nxt;
}E[MAXN << 1];
int head[MAXN], num = 1;
inline void AddEdge(int x, int y, int z) {E[num] = (Edge) {x, y, z, head[x]};head[x] = num++;
}
vector<int> v[MAXN];
void add_edge(int x, int y) {v[x].push_back(y);
}
int a[MAXN], dfn[MAXN], topf[MAXN], siz[MAXN], son[MAXN], s[MAXN], top, deep[MAXN], fa[MAXN], ID = 0;
LL mn[MAXN];
void dfs1(int x, int _fa) {siz[x] = 1; fa[x] = _fa;for(int i = head[x]; i != -1; i = E[i].nxt) {if(E[i].v == _fa) continue;deep[E[i].v] = deep[x] + 1;mn[E[i].v] = min(mn[x], (LL)E[i].w);dfs1(E[i].v, x);siz[x] += siz[E[i].v];if(siz[E[i].v] > siz[son[x]]) son[x] = E[i].v;}
}
void dfs2(int x, int topfa) {topf[x] = topfa;dfn[x] = ++ID;if(!son[x]) return ;dfs2(son[x], topfa);for(int i = head[x]; i != -1; i = E[i].nxt) if(!topf[E[i].v]) dfs2(E[i].v, E[i].v);
}
int LCA(int x, int y) {while(topf[x] != topf[y]) {if(deep[topf[x]] < deep[topf[y]]) swap(x, y);x = fa[topf[x]];}if(deep[x] < deep[y]) swap(x, y);return y;
}
void insert(int x) {if(top == 1) {s[++top] = x; return ;}int lca = LCA(x, s[top]);if(lca == s[top]) return ;//以为s[top]也是关键点,那么s[top]子树里的点就没必要处理了 while(top > 1 && dfn[s[top - 1]] >= dfn[lca]) add_edge(s[top - 1], s[top]), top--;if(lca != s[top]) add_edge(lca, s[top]), s[top] = lca;//s[++top] = x;
}
LL DP(int x) {if(v[x].size() == 0) return mn[x];LL sum = 0;for(int i = 0; i < v[x].size(); i++) sum += DP(v[x][i]);v[x].clear();return min(sum, (LL)mn[x]);
}
int comp(const int &a, const int &b) {return dfn[a] < dfn[b];
}
int main() {memset(head, -1, sizeof(head));//memset(mn, 0xff, sizeof(mn));mn[1] = 1ll << 60;N = read();for(int i = 1; i <= N - 1; i++) {int x = read(), y = read(), z = read();AddEdge(x, y, z); AddEdge(y, x, z);}deep[1] = 1;dfs1(1, 0);dfs2(1, 1);M = read();/*for(int i = 1; i <= N; i++)    for(int j = 1; j <= N; j++)printf("%d %d %d\n", i, j, LCA(i, j));*///for(int i = 1; i <= N; i++) printf("%d ", mn[i]); puts("");while(M--) {int K = read();for(int i = 1; i <= K; i++) a[i] = read();sort(a + 1, a + K + 1, comp);s[top = 1] = 1;for(int i = 1; i <= K; i++) insert(a[i]);while(top > 0)  add_edge(s[top - 1], s[top]), top--;print(DP(1)), *O++ = '\n'; }fwrite(obuf, O-obuf, 1 , stdout);    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【做题记录】CF1428E Carrots for Rabbits—堆的妙用

CF1428E Carrots for Rabbits 题意&#xff1a; 有 \(n\) 个萝卜&#xff0c;每个萝卜的初始大小为 \(a_i\) 。现在要把这些萝卜切为为 \(k\) 个。吃每一个萝卜的时间为这个萝卜的大小的平方&#xff0c;求吃完所有萝卜的最小时间&#xff0c;即 \(\sum_{i1}^{k}{a_i^2}\) 最小…

P4716-[模板]最小树形图

正题 题目链接:https://www.luogu.com.cn/problem/P4716 题目大意 给出nnn个点mmm条边的一张有向图&#xff0c;求以rrr为根的最小外向树。 1≤n≤100,1≤m≤1041\leq n\leq 100,1\leq m\leq 10^41≤n≤100,1≤m≤104 解题思路 考虑一种贪心&#xff0c;对于每个点我们先选出…

P1081 [NOIP2012 提高组] 开车旅行(倍增)(动态规划)

洛谷传送门 文章目录题目描述解析代码题目描述 解析 利用倍增&#xff0c;设计dp慢慢敲即可。。。 注意距离累加在一起会爆int&#xff0c;需要ll 特判条件非常之复杂。。。 心力交瘁&#xff0c;就酱了 代码 #include <bits/stdc.h> using namespace std; #define ll…

dotnet core调试docker下生成的dump文件

最近公司预生产环境.net core应用的docker容器经常出现内存暴涨现象&#xff0c;有时会突然吃掉几个G,触发监控预警&#xff0c;造成容器重启。分析了各种可能原因&#xff0c;修复了可能发生的内存泄露&#xff0c;经测试本地正常&#xff0c;但是发到预生产还是会有内存暴涨现…

【做题记录】区间排序—线段树

1. CF558E A Simple Task 题意&#xff1a; 给定由小写字母组成的字符串 \(s\) 每一次操作如下&#xff1a; \(opt0\) &#xff1a;将 \([l,r]\) 降序排序 \(opt1\) &#xff1a;将 \([l,r]\) 升序排序 输出最终字符串 题解&#xff1a; 大致思想为&#xff0c;建 \(26\) 棵线…

Quadratic Form

Quadratic Form 题意&#xff1a; 一个n * n 的正定矩阵和一个n维的向量b&#xff0c;现在找一个x1&#xff0c;x2&#xff0c;…xn满足以下条件&#xff1a; 求这个式子&#xff0c;最后输出P * Q-1 mod 998244353. 题解&#xff1a; 参考 线性代数学过n阶正定的实矩阵等…

P3426-[POI2005]SZA-Template【KMP】

正题 题目链接:https://www.luogu.com.cn/problem/P3426 题目大意 给出一个长度为nnn的字符串sss&#xff0c;求一个长度最小的字符串ttt使得sss所有ttt和ttt匹配的位置能覆盖串sss。 1≤n≤51051\leq n\leq 5\times 10^51≤n≤5105 解题思路 首先答案肯定是原串的一个borde…

8分钟学会Consul集群搭建及微服务概念

Consul介绍&#xff1a;Consul 是由 HashiCorp 公司推出的开源软件&#xff0c;用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案&#xff0c;Consul 的方案更“一站式”&#xff0c;内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Valu…

取模除法(逆元)(费马小定理)(线性求逆元)

文章目录引言逆元费马小定理内容应用证明线性求逆元thanks for reading&#xff01;引言 我们做题时经常会由于答案过大&#xff0c;被要求使答案对一个质数取模 我们都知道&#xff0c;加和乘对取模是没有影响的 减法也只需要写一个&#xff1a; int mod_minus(int a,int b)…

数学基础知识(高精、快速幂、龟速乘……)

压位高精 模板代码 龟速乘 ll ch(ll x,ll y) {ll ret0;while(y){if(y&1) ret(retx)%m;x(xx)%m,y>>1;}return ret; }

P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包

P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包 题目&#xff1a; 给定一些点&#xff0c;问围住所有点所用的围栏的长度 题解&#xff1a; 凸包模板题 凸包详细 代码&#xff1a; #include<iostream> #include<algorithm> #include<cstdio&g…

最小代价(区间dp)(ybtoj)

文章目录题目描述解析代码题目描述 解析 &#xff08;我觉得&#xff09;很难的dp 思路是真的没有想出来 关键在于dp的设计&#xff1a; dp[l][r]&#xff1a;[l,r]的最小价值 f[l][r][a][b]&#xff1a;把l到r之间除了数值在[a,b]之间的数全部消掉需要的最小价值 &#xff08…

P4783-[模板]矩阵求逆

正题 题目链接:https://www.luogu.com.cn/problem/P4783 题目大意 给出一个矩阵&#xff0c;求它的逆矩阵。 1≤n≤4001\leq n\leq 4001≤n≤400 解题思路 记给出矩阵PPP&#xff0c;记单位矩阵EEE。 PP−1E⇒P(EP−1)EP\times P^{-1}E\Rightarrow P\times (E\times P^{-1})…

.net core i上 K8S(六).netcore程序的service网络代理模式

正文上一章我们讲了pod的hostip模式&#xff0c;但在生产环境中&#xff0c;我们都是通过service来访问k8s集群的&#xff0c;service有两种模式来暴漏端口&#xff0c;今天我们来分享一下1.clusterIP模式我们在创建service的时候&#xff0c;默认创建的时clusterIP模式&#x…

CF183D-T-shirtx【dp,贪心】

正题 题目链接:https://www.luogu.com.cn/problem/CF183D 题目大意 nnn个人&#xff0c;mmm种衣服&#xff0c;给出每个人喜欢某件衣服的概率&#xff0c;你可以选择nnn件衣服带过去&#xff08;可以重复款式&#xff09;。求最大化能拿到喜欢衣服人的期望数量。 1≤n≤3000,1…

Jamie and Tree[CF916E]

Jamie and Tree[CF916E] 题意&#xff1a; 有一棵n个点的树&#xff0c;每个节点上有一个权值wi&#xff0c;最开始根为1号点&#xff0e;现在有3种 类型的操作&#xff1a; • 1 root, 表示将根设为root. • 2 u v x, 设u, v的最近公共祖先为p, 将p的子树中的所有点的权值加…

领域驱动设计,让程序员心中有码(三)

“正如西方古典哲学在现代社会逐渐式微&#xff0c;成为少数内心丰满者们填充自己精神世界的宝贵食物&#xff0c;UML也这样&#xff1b;互联网技术飞速发展的今天&#xff0c;各类软件设计思想层出不穷&#xff0c;正是站在UML和其他各种软件基础理论巨人的肩膀上&#xff0c;…

P4127 [AHOI2009]同类分布(数位dp)

洛谷传送门 文章目录题目描述解析代码题目描述 给出两个数a,b求出[a,b]中各位数字之和能整除原数的数的个数。 1<a<b<1018 解析 容易想到数位dp 但本题的难点是如果只记录数位和sum与取模的结果res&#xff0c;因为取模的除数发生改变&#xff0c;难以转移 如何解决…

线性代数(矩阵、高斯、线性基……)

矩阵 矩阵加法&#xff1a; 相同位置相加。 矩阵乘法&#xff1a; 满足分配率、结合律&#xff0c;不满足交换律(矩阵与逆矩阵之间除外) 。 矩阵转置&#xff1a; 记矩阵为 \(A\) &#xff0c;则 \(A\) 的转置记为 \(A^T\) 。 性质&#xff1a; \[{(A^T)}^TA \]\[{(AB)}^TA^TB^…

Tavan

Tavan–简单的k进制题 呵呵真的简单 也就是考试没做出来罢了&#xff0c;不慌不慌&#xff0c;奶我一口&#xff0c;还能活 【题目摘要】 题目描述 小 Zeljko 一直在阁楼里读他奶奶的旧信&#xff0c;并且发现了一个长度为 N 的单词。 不幸的是&#xff0c;由于溢出的墨水&…