跑一遍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[最小生成树+树剖+线段树]的更多相关文章

  1. BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...

  2. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  3. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  4. 【BZOJ5210】最大连通子块和 树剖线段树+动态DP

    [BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...

  5. [LNOI2014]LCA(树剖+线段树)

    \(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...

  6. [CF1007D]Ants[2-SAT+树剖+线段树优化建图]

    题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...

  7. LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)

    题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...

  8. BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)

    传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...

  9. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  10. 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 ...

随机推荐

  1. English 邮件

    1.email http://www2.elc.polyu.edu.hk/cill/eiw/e-mail.htm

  2. golang struct 转map 及 map[string]*Struct 初始化和遍历

    package main import ( "encoding/json" "errors" "fmt" "reflect&quo ...

  3. Laravel注册登陆认证API

    注册接口 路由api.php:Route::post('register', 'Auth\RegisterController@register'); 控制器 http//controllers/au ...

  4. [转帖]如何在Linux上使用命令行查看硬件信息

    如何在Linux上使用命令行查看硬件信息 时间:2016-01-13   作者:admin 分类:新手入门 阅读:126次 http://embeddedlinux.org.cn/emb-linux/ ...

  5. 阿里云云计算ACP专业认证考试

    阿里云云计算专业认证(Alibaba Cloud Certified Professional,ACP)是面向使用阿里云云计算产品的架构.开发.运维类人员的专业技术认证. 更多阿里云云计算ACP专业认 ...

  6. PostgreSQL查看表、表索引、视图、表结构以及参数设置

    -- 表索引select * from pg_indexes where tablename='person_wechat_label';select * from pg_statio_all_ind ...

  7. 并不对劲的CF1239B&C&D Programming Task in the Train to Catowice City

    CF1239B The World Is Just a Programming Task 题目描述 定义一个括号序列s是优秀的,当且仅当它是以下几种情况的一种: 1.|s|=0 2.s='('+t+' ...

  8. Wannafly挑战赛24

    A. 石子游戏 Alice和Bob在玩游戏,他们面前有n堆石子,对于这些石子他们可以轮流进行一些操作,不能进行下去的人则输掉这局游戏.可以进行两种操作:1. 把石子数为奇数的一堆石子分为两堆正整数个石 ...

  9. Django+celery+rabbitmq实现邮件发送

    一.环境 1.pip包 amqp==2.4.2 anyjson==0.3.3 billiard==3.6.0.0 celery==4.3.0 Django==2.2 dnspython==1.16.0 ...

  10. Java Web ActiveMQ与WebService的异同

    Webservice 和MQ(MessageQueue)都是解决跨平台通信的常用手段 一.WebService:用来远程调用服务,达到打通系统.服务复用的目的.是SOA系统架构——面向服务架构的体现. ...