BZOJ_2238_Mst_ tree section + line segment tree

BZOJ_2238_Mst_ tree section + line segment tree

Description

Given an undirected weighted graph with N points and M edges, and Q queries, each querying the minimum spanning tree of the graph after deleting an edge in the graph. ( Each query is independent, and each query does not affect subsequent queries, that is, the deleted edge still exists in the next query )

Input

The first line of two positive integers N, M (N<=50000, M<=100000) represents the number of vertices and edges of the original graph.
The following M lines, each line of three integers X, Y, W describe an edge (X, Y) of the graph, and its edge weight is W (W<=10000). It is guaranteed that there is at most one edge between two points.
The next line contains a positive integer Q, which represents the number of queries. (1<=Q<=100000)
The following Q lines, each line contains a query, and the query contains a positive integer T, which means to delete the edge numbered T (edges are numbered from 1 to M in the order of input).

Output

Line Q , for each query output the value of the edge weights corresponding to the minimum spanning tree, and output "Not connected" if the graph is 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


 

We first find an arbitrary minimum spanning tree.

If the deleted edge (x->y) is not in the tree, just output the edge weight sum of the minimum spanning tree directly.

Otherwise, we need to find the one with the smallest edge weight among all the edges that can connect the two points of x and y, and replace it.

When inserting each non-tree edge, use the weight of this edge to update the minimum value of the weight on the x->y path on the tree, and record the number of the edge with the smallest edge weight.

Then this can be maintained with tree section + line segment tree.

Note that if the graph is not connected, output Not connected,

 

Code:

#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; you [x] = 1;
	for(i=head[x];i;i=nxt[i]) {
		if(to[i]!=y) {
			ref[val[i]]=to[i];
			dfs1 (to [i], x); you [x] + = you [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\n",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\n",sum-a[k].z+re);
			}
		}
	}
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325338593&siteId=291194637