BZOJ2238 Mst[最小生成树+树剖+线段树]
跑一遍mst。对于非mst上的边,显然删掉不影响。
如果删边在树上,相当于这时剩下两个连通块。可以证明要重新构成mst只需要再加一条连接两个连通块的最小边,不会证,yy一下,因为原来连通块连的边权和已经最小化了,就不要动,如果换用两条以上的边,肯定不会更优。
所以问题就是断掉树边,找最小联通边。可以LCT。`````
这种一颗树断成两截找联通边的题有一个常用思路,要使得联通,必须得有非树边两端点形成的链过这个断边。换句话说,一条非树边两点形成的树上链可以在树断掉后成为联通边当且仅当他经过的边断掉。
这个思路应该在先前这个poj题「闇の連鎖」中出现过,很容易证。其实换句话说这个跟次小生成树做法比较像。
那么只要看经过这个断边的所有非树边中最小的是哪个,用他来联通,总体来看,就是把每条非树边路径上用自己的代价更新一波最小值。
用线段树打标记维护,最后查询的时候直接查单点最小值计算答案即可。
注意判无解。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=1e5+,INF=0x3f3f3f3f;
struct thxorz{int to,nxt,w;}G[N];
int Head[N],tot,used[N];
int n,m,q;
inline void Addedge(int x,int y,int z){
G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;
G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot,G[tot].w=z;
}
struct stothx{
int u,v,w,id;
inline bool operator <(const stothx&x)const{return w<x.w;}
}E[N],_E[N];
int anc[N],ans;
int get_anc(int x){return x==anc[x]?x:anc[x]=get_anc(anc[x]);}
int fa[N],topfa[N],son[N],cnt[N],d[N],st[N],tim;
#define y G[j].to
void dfs1(int x,int f){
fa[x]=f,d[x]=d[f]+,cnt[x]=;int tmp=-;
for(register int j=Head[x];j;j=G[j].nxt)if(y^f)dfs1(y,x),cnt[x]+=cnt[y],MAX(tmp,cnt[y])&&(son[x]=y);
}
void dfs2(int x,int topf){
topfa[x]=topf,st[x]=tim++;if(!son[x])return;dfs2(son[x],topf);
for(register int j=Head[x];j;j=G[j].nxt)if(y^fa[x]&&y^son[x])dfs2(y,y);
}
#undef y
#define lc i<<1
#define rc i<<1|1
int minv[N<<],mtag[N<<];
inline void pushup(int i){minv[i]=_min(minv[lc],minv[rc]);}
inline void pushdown(int i){
if(mtag[i]<INF)
MIN(minv[lc],mtag[i]),MIN(minv[rc],mtag[i]),MIN(mtag[lc],mtag[i]),MIN(mtag[rc],mtag[i]),mtag[i]=INF;
}
void Update(int i,int L,int R,int ql,int qr,int val){//dbg(L),dbg(R),dbg(ql),dbg(qr);
if(ql<=L&&qr>=R){MIN(minv[i],val),MIN(mtag[i],val);return;}
int mid=L+R>>;pushdown(i);
if(ql<=mid)Update(lc,L,mid,ql,qr,val);
if(qr>mid)Update(rc,mid+,R,ql,qr,val);
pushup(i);
}
int Query_min(int i,int L,int R,int x){
if(L==R)return minv[i];
int mid=L+R>>;pushdown(i);
return x<=mid?Query_min(lc,L,mid,x):Query_min(rc,mid+,R,x);
}
inline void Tree_update(int x,int y,int z){
while(topfa[x]^topfa[y]){
if(d[topfa[x]]<d[topfa[y]])x^=y^=x^=y;
Update(,,n-,st[topfa[x]],st[x],z),x=fa[topfa[x]];
}
if(d[x]>d[y])x^=y^=x^=y;
if(x^y)Update(,,n-,st[x]+,st[y],z);
}
inline void mst(){
sort(E+,E+m+);int res=;
for(register int i=;i<=n;++i)anc[i]=i;
for(register int i=;i<=m;++i)
if(get_anc(E[i].u)^get_anc(E[i].v)){
anc[get_anc(E[i].v)]=get_anc(E[i].u);
used[E[i].id]=,ans+=E[i].w;++res;
Addedge(E[i].u,E[i].v,E[i].w);
}
if(res<n-){while(q--)puts("Not connected");exit();}
dfs1(,),dfs2(,);
memset(mtag,0x3f,sizeof mtag),memset(minv,0x3f,sizeof minv);
for(register int i=;i<=m;++i){
if(used[i])used[i]=d[_E[i].u]<d[_E[i].v]?_E[i].v:_E[i].u;
else Tree_update(_E[i].u,_E[i].v,_E[i].w);
}
}
int id;
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n);read(m);
for(register int i=;i<=m;++i)_E[i].u=read(E[i].u),_E[i].v=read(E[i].v),_E[i].w=read(E[i].w),E[i].id=i;
read(q);mst();
while(q--){
read(id);if(!used[id]){printf("%d\n",ans);continue;}
int tmp=Query_min(,,n-,st[used[id]]);
if(tmp<INF)printf("%d\n",ans-_E[id].w+tmp);
else puts("Not connected");
}
return ;
}
反思:注意这个提到的常用思路,即化非树边为树上链的边覆盖问题。
BZOJ2238 Mst[最小生成树+树剖+线段树]的更多相关文章
- BZOJ_2238_Mst_树剖+线段树
BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...
- BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树
BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...
- BZOJ_2157_旅游_树剖+线段树
BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
- 【BZOJ5210】最大连通子块和 树剖线段树+动态DP
[BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...
- [LNOI2014]LCA(树剖+线段树)
\(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...
- [CF1007D]Ants[2-SAT+树剖+线段树优化建图]
题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...
- LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)
题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...
- BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)
传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...
- 【bzoj4699】树上的最短路(树剖+线段树优化建图)
题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...
- POJ3237 Tree(树剖+线段树+lazy标记)
You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbe ...
随机推荐
- 论文阅读 | TextBugger: Generating Adversarial Text Against Real-world Applications
NDSS https://arxiv.org/abs/1812.05271 摘要中的创新点确实是对抗攻击中值得考虑的点: 1. effective 2. evasive recognized b ...
- 关于keildownload键变为灰色不能使用的问题
有时候 有些朋友可能会遇到这样的问题 突然间download键变成灰色,导致不能将程序下载到芯片中 遇到中问题如果不是软件卡了 那就是可能一不小心点错了,关掉了下载条件“约定” 可以点“魔术棒” ...
- 阿里EMR部署
选自定义购买: 选择master配置: 选择core配置: 下一步,选高级里在jdbc后填RDS的url, 用户名,密码: jdbc:mysql://rm-d7o7x76l11u0434zn.mysq ...
- 【Python】【demo实验16】【练习实例】【打印所有水仙花数】
题目: 打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身.例如:153是一个"水仙花数",因为153= ...
- Centos7 + nginx 托管 Django 项目
使用nginx托管django服务的原理 使用uwsgi开启django服务(通过配置文件启动) 防火墙关闭uwsgi端口(uwsgi的websocket一定要使用127.0.0.1的方式配置)) 编 ...
- Django模板(Template)系统
Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. 点 ...
- postpreSQL和oracle数据库的递归
oracle: --包含自身 select * from sec_org start with org_id ='9767FA56D52680AEE043C0A8670580AE' --开始节点 co ...
- java lesson13Homework
/** * 1. 字符串解析,现有字符串,“卡巴斯基#杀毒软件#免费版#俄罗斯#”,解析出每个元素. */ package String13Practice; public class String0 ...
- HttpWorkerRequest应用简介
1. Using HttpWorkerRequest for getting headers1.使用HttpWorkerRequest获取headers信息 First, the HttpWorker ...
- 【vue】computed 和 watch
计算属性:computed 监听多个变量且变量是在vue实例中(依赖某个变量,变量发生改变就会触发) 侦听器: watch 监听一个变量的变化 使用场景:watch(异步场景) ...