链接

题解

先构建出最小生成树,如果删的是非树边,直接输出答案

否则问题转化为,把该边删掉后剩下两个联通块,两个端点分别在两个块内的最小边权,LCT可以维护

不妨换一种思考方向:考虑一条非树边可以代替哪些树边,根据次小生成树的套路,它可以代替树上两端点之间路径上的任意一条边

因此,对MST进行树链剖分,然后对每一条非树边更新它两端点之间路径的最小值即可

注意:题目给的图可能不连通,需要特判!

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int>pii;
inline int read(){char c,p=0;int w;
while(isspace(c=getchar()));if(c=='-')p=1,c=getchar();
for(w=c&15;isdigit(c=getchar());w=w*10+(c&15));return p?-w:w;
}
template<typename T,typename U>inline char smin(T&x,const U&y){return x>y?x=y,1:0;}
template<typename T,typename U>inline char smax(T&x,const U&y){return x<y?x=y,1:0;}
namespace IOManager{
const unsigned int iSize(131072),oSize(65536);
char buf[iSize],wbuf[oSize+128],*iT=buf+iSize,*iS=iT-1,*oS=wbuf-1,*oT=wbuf+oSize;
struct FastIO{
inline char gc(){
if(++iS==iT)fread(iS=buf,1,iSize,stdin);return *iS;
}
template<typename T>
inline void read(T&w){register char c,p=0;
while(isspace(c=gc()));if(c=='-')p=1,c=gc();w=c^48u;
while(isdigit(c=gc()))w=w*10+(c^48u);if(p)w=-w;
}
inline int read(){register int x;return read(x),x;}
inline void flush(){fwrite(wbuf,1,oS-wbuf+1,stdout);oS=wbuf-1;}
~FastIO(){flush();}
inline FastIO&operator<<(const char&c){if(oS>oT)flush();*++oS=c;}
inline void putstr(const string&s){
const int l=s.length();
if(oS>oT)flush();
for(int i=0;i<l;++i)*++oS=s[i];
}
template<typename T>
inline FastIO&operator<<(T x){
static char stk[30];int top=0;
if(oS>oT)flush();
if(x==0)return *++oS='0',*this;
if(x<0)x=-x,*++oS='-';
for(;x;x/=10)stk[++top]=x%10^48;
while(top)*++oS=stk[top--];
return*this;
}
};
}IOManager::FastIO io;
#define read io.read
const int N=50005;
int n,m,tot,head[N],vis[N<<1],to[N<<1],nxt[N<<1],top[N],siz[N],in[N],son[N],dep[N],fa[N],cnt;
struct edge{int u,v,w,id;}a[N<<1],b[N<<1];
inline void add(int x,int y){to[++tot]=y,nxt[tot]=head[x];head[x]=tot;}
#define y to[i]
inline void go1(int x){
siz[x]=1;
for(int i=head[x];i;i=nxt[i])if(y!=fa[x])
fa[y]=x,dep[y]=dep[x]+1,go1(y),siz[x]+=siz[y],siz[y]>siz[son[x]]&&(son[x]=y);
}
inline void go2(int x,int anc){
in[x]=++cnt,top[x]=anc;
if(!son[x])return;go2(son[x],anc);
for(int i=head[x];i;i=nxt[i])if(y!=fa[x]&&y!=son[x])go2(y,y);
}
#undef y
inline bool cmp(edge x,edge y){return x.w<y.w;}
int pa[N];
inline int find(int x){return pa[x]?pa[x]=find(pa[x]):x;}
int tag[N<<2];
#define ls o<<1
#define rs o<<1|1
inline void update(int o,int l,int r,int x,int y,int z){
if(z>tag[o])return;
if(x<=l&&r<=y)return (void)(tag[o]=z);
int mid=l+r>>1;
if(x<=mid)update(ls,l,mid,x,y,z);
if(y>mid)update(rs,mid+1,r,x,y,z);
}
inline int ask(int o,int l,int r,int x){
int ans=tag[0];
while(1){
smin(ans,tag[o]);
if(l==r)return ans;
int mid=l+r>>1;
x<=mid?(o=ls,r=mid):(o=rs,l=mid+1);
}
return -1;
}
inline void update(int x,int y,int z){
while(top[x]^top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(1,1,n,in[top[x]],in[x],z);x=fa[top[x]];
}
if(x==y)return;
if(dep[x]>dep[y])swap(x,y);
update(1,1,n,in[x]+1,in[y],z);
}
int main(){
n=read(),m=read();
REP(i,1,m)a[i]=b[i]=(edge){read(),read(),read(),i};
sort(a+1,a+1+m,cmp);
int ans=0;
REP(i,1,m){
int x=find(a[i].u),y=find(a[i].v);
if(x!=y)
add(a[i].u,a[i].v),add(a[i].v,a[i].u),
pa[x]=y,vis[a[i].id]=1,ans+=a[i].w;
}
go1(1),go2(1,1);
if(siz[1]<n){
int Q=read();
while(Q--)io.putstr("Not connected\n");
return 0;
}
memset(tag,0x3f,sizeof tag);
REP(i,1,m)if(!vis[i])update(b[i].u,b[i].v,b[i].w);
int Q=read();
while(Q--){
int id=read();
if(!vis[id])io<<ans<<'\n';
else{
int&x=b[id].u,&y=b[id].v;
if(dep[x]<dep[y])swap(x,y);
int r=ask(1,1,n,in[x]);
if(r==tag[0])io.putstr("Not connected\n");
else io<<ans-b[id].w+r<<'\n';
}
}
return 0;
}

UPD.20181107

根据BZOJ2054疯狂的馒头的思想,这题可以用并查集优化,思路与上文相同

复杂度 \(O(\alpha(n)\times n)\)

代码没时间写了,就咕了吧。。

[BZOJ2238]Mst 最小生成树+树链剖分/并查集的更多相关文章

  1. hdu 5458 Stability(树链剖分+并查集)

    Stability Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total ...

  2. 【bzoj2238】Mst 最小生成树+树链剖分+线段树

    题目描述 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影响,即被删掉的边在下一条询问中依然存在) 输入 第一行两 ...

  3. HDU 5458 Stability (树链剖分+并查集+set)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 给你n个点,m条边,q个操作,操作1是删边,操作2是问u到v之间的割边有多少条. 这题要倒着做才 ...

  4. bzoj3694: 最短路(树链剖分/并查集)

    bzoj1576的帮我们跑好最短路版本23333(双倍经验!嘿嘿嘿 这题可以用树链剖分或并查集写.树链剖分非常显然,并查集的写法比较妙,涨了个姿势,原来并查集的路径压缩还能这么用... 首先对于不在最 ...

  5. 【bzoj2238】Mst(树链剖分+线段树)

    2238: Mst Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 465  Solved: 131[Submit][Status][Discuss] ...

  6. HDU3710 Battle over Cities(最小生成树+树链剖分+倍增+线段树)

    Battle over Cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  7. Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)

    题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...

  8. [wikioi 1519]过路费(最小生成树+树链剖分)

    题目:http://www.wikioi.com/problem/1519/ 题意:给你一个连通的无向图,每条边都有权值,给你若干个询问(x,y),要输出从x到y的路径上边的最大值的最小值 分析:首先 ...

  9. Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

随机推荐

  1. Linux查看当前正在执行的进程

    Linux查看当前正在执行的进程 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ps PID TTY TIME CMD 2576 pts/0 00:00:00 ...

  2. Linux系统编程——进程间通信:信号中断处理

    什么是信号? 信号是 Linux 进程间通信的最古老的方式.信号是url=474nN303T2Oe2ehYZjkrggeXCaJPDSrmM5Unoh4TTuty4wSgS0nl4-vl43AGMFb ...

  3. 并查集树数据结构hdu1325

    我的解法就是去构造了一棵树 以数组的存储方式 数组的值存放节点的根. 排除空树 剩下的就是出现环和多根节点的情况 也就是排除森林和有一个节点多个入度的情况 排除森林就用到了并查集 也就是便利数组让其仅 ...

  4. 免费WiFi初体验——个小白的WiFi旅程

    说来羞愧,真正接触到WiFi还是在毕业后,此前自己封闭在一个人的世界,再加上外在学校的包围,我还成了个"山里"的孩子. 去年毕业了,也算是个90后,可自觉得心态过于成熟.了解外界太 ...

  5. Controller接口控制器3

    11.AbstractWizardFormController 向导控制器类提供了多步骤(向导)表单的支持(如完善个人资料时分步骤填写基本信息.工作信息.学校信息等) 假设现在做一个完善个人信息的功能 ...

  6. 相比于HTML4,HTML5废弃的元素有哪些?

    第一类:表现性元素basefontbigcenterfontsstrikettu建议用语义正确的元素代替他们,并使用CSS来确保渲染后的效果 第二类:框架类元素因框架有很多可用性及可访问性问题,HTM ...

  7. jdbc参数传递

    1.jdbc请求设置 将查询结果第一列coupon_id,存放在couponId中; 将查询结果第二列code,存放在coupCode中 2.参数解释: couponId_#:表示查询结果中coupo ...

  8. 原生js模拟jquery中的addClass和removeClass方法

    js代码: //添加类 function addClass(obj,className) { if(obj.className == '') { //如果没有class obj.className = ...

  9. Mirai僵尸网络重出江湖

    近年数度感染数十万台路由器的僵尸网络程序Mirai,虽然原创者已经落网判刑,但是Mirai余孽却在网络上持续变种,现在安全人员发现,Mirai已经将焦点转向Linux服务器了. 安全公司Netcout ...

  10. Python3爬虫之爬取某一路径的所有html文件

    要离线下载易百教程网站中的所有关于Python的教程,需要将Python教程的首页作为种子url:http://www.yiibai.com/python/,然后按照广度优先(广度优先,使用队列:深度 ...