zoukankan      html  css  js  c++  java
  • BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树

    Description

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

    Input

    第一行两个正整数N,M(N<=50000,M<=100000)表示原图的顶点数和边数。
    下面M行,每行三个整数X,Y,W描述了图的一条边(X,Y),其边权为W(W<=10000)。保证两点之间至多只有一条边。
    接着一行一个正整数Q,表示询问数。(1<=Q<=100000)
    下面Q行,每行一个询问,询问中包含一个正整数T,表示把编号为T的边删掉(边从1到M按输入顺序编号)。

    Output

    Q行,对于每个询问输出对应最小生成树的边权和的值,如果图不连通则输出“Not connected”

    Sample Input

    4 4
    1 2 3
    1 3 5
    2 3 9
    2 4 1
    4
    1
    2
    3
    4

    Sample Output

    15
    13
    9
    Not connected


    我们先求任意一棵最小生成树。

    如果被删除的边(x->y)不在树上,则直接输出最小生成树的边权和即可。

    否则我们要找到所有能使x,y两点连通的边中边权最小的那个,把它换上。

    在插入每条非树边时用这条边的权值更新树上x->y路径上权值的最小值,同时记录边权最小的边的编号。

    然后这个可以用树剖+线段树维护出来。

    注意如果图不联通要输出Not connected,

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define ls p<<1
    #define rs p<<1|1
    #define N 100050
    int head[N],to[N<<1],nxt[N<<1],cnt,n,m;
    int mn[N<<2],f[N],sum,ref[N],val[N<<1];
    int dep[N],fa[N],top[N],siz[N],son[N],idx[N],tot;
    struct A {
    	int x,y,z,flg,id;
    }a[N];
    bool cmp1(const A &x,const A &y) {return x.z<y.z;}
    bool cmp2(const A &x,const A &y) {return x.id<y.id;}
    int find(int x) {
    	return f[x]==x?x:f[x]=find(f[x]);
    }
    inline void add(int u,int v,int w) {
    	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
    }
    void dfs1(int x,int y) {
    	int i;
    	dep[x]=dep[y]+1; fa[x]=y; siz[x]=1;
    	for(i=head[x];i;i=nxt[i]) {
    		if(to[i]!=y) {
    			ref[val[i]]=to[i];
    			dfs1(to[i],x); siz[x]+=siz[to[i]];
    			if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
    		}
    	}
    }
    void dfs2(int x,int t) {
    	top[x]=t;idx[x]=++tot;
    	if(son[x]) dfs2(son[x],t);
    	int i;
    	for(i=head[x];i;i=nxt[i]) {
    		if(to[i]!=fa[x]&&to[i]!=son[x]) {
    			dfs2(to[i],to[i]);
    		}
    	}
    }
    void update(int l,int r,int x,int y,int v,int p) {
    	if(x<=l&&y>=r) {
    		mn[p]=min(mn[p],v); return ;
    	}
    	int mid=(l+r)>>1;
    	if(x<=mid) update(l,mid,x,y,v,ls);
    	if(y>mid) update(mid+1,r,x,y,v,rs);
    }
    int query(int l,int r,int x,int p) {
    	if(l==r) return mn[p];
    	int mid=(l+r)>>1;
    	if(x<=mid) return min(mn[p],query(l,mid,x,ls));
    	else return min(mn[p],query(mid+1,r,x,rs));
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	int i,ne=0,x,y;
    	for(i=1;i<=n;i++) f[i]=i;
    	for(i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z),a[i].id=i;
    	sort(a+1,a+m+1,cmp1);
    	for(i=1;i<=m;i++) {
    		int dx=find(a[i].x),dy=find(a[i].y);
    		if(dx!=dy) {
    			add(a[i].x,a[i].y,a[i].id);
    			add(a[i].y,a[i].x,a[i].id);
    			ne++;
    			f[dx]=dy;
    			a[i].flg=1;
    			sum+=a[i].z;
    			if(ne==n-1) break;
    		}
    	}
    	int q;
    	if(ne<n-1) {
    		scanf("%d",&q);
    		while(q--) {
    			puts("Not connected");
    		}
    		return 0;
    	}
    	dfs1(1,0); dfs2(1,1);
    	for(i=1;i<=4*n;i++) mn[i]=1<<30;
    	sort(a+1,a+m+1,cmp2);
    	for(i=1;i<=m;i++) {
    		if(!a[i].flg) {
    			x=a[i].x,y=a[i].y;
    			while(top[x]!=top[y]) {
    				if(dep[top[x]]>dep[top[y]]) swap(x,y);
    				update(1,n,idx[top[y]],idx[y],a[i].z,1);
    				y=fa[top[y]];
    			}
    			if(dep[x]<dep[y]) swap(x,y);
    			if(x!=y)update(1,n,idx[y]+1,idx[x],a[i].z,1);
    		}
    	}
    	int k;
    	scanf("%d",&q);
    	while(q--) {
    		scanf("%d",&k);
    		if(!a[k].flg) {
    			printf("%d
    ",sum);
    		}else {
    			x=a[k].x;y=a[k].y;
    			int re=query(1,n,idx[ref[k]],1);
    			if(re==(1<<30)) {
    				puts("Not connected");
    			}else {
    				printf("%d
    ",sum-a[k].z+re);
    			}
    		}
    	}
    }
    
  • 相关阅读:
    Git .gitignore文件简介及使用
    JMeter 报告监听器导入.jtl结果文件报错解决方案
    JMeter 中实现发送Java请求
    JMeter 正则表达式提取器结合ForEach控制器遍历提取变量值
    Tomcat_记一次tomcatwar包应用简单部署过程
    Python_基于Python同Linux进行交互式操作实现通过堡垒机访问目标机
    Python_关于多线程下变量赋值取值的一点研究
    JMeter 后置处理器之正则表达式提取器详解
    性能测试 CentOS下结合InfluxDB及Grafana图表实时展示JMeter相关性能数据
    Python 标准类库-数据类型之copy-深拷贝浅拷贝操作
  • 原文地址:https://www.cnblogs.com/suika/p/8995842.html
Copyright © 2011-2022 走看看