【BZOJ 3732】Network kruskal树

原创 2017年01月03日 08:53:08

今天听同学介绍的,就把这道题写了,还有去做了BZOJ3551也会用到,不过会套一个主席树。

kruskal树(应该就叫这个名字吧,叫错了也不怪我qwq),思想就是把边权转化成点权,每一次连边的时候就新建一个虚拟节点,然后像原来的两个节点的根节点连边,点权就是连接两边的边的边权,然后他具有很多有趣而显然的性质,例如真实节点是叶子节点,点权沿链向上递增等等可以自己去发掘,这道题就是先建立一个最小生成树,然后查询最小生成树中两点边的最大值,证明很简单就不写了,刚好可以用上。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 60020
using namespace std;
int head[maxn],tot=1,n,m,Q,f[maxn][20],ff[maxn],cnt,dep[maxn],val[maxn];
int find(int x){return ff[x]==x ? x : ff[x]=find(ff[x]);}
struct data{
	int a,b,c;
	bool operator<(const data& y)const {return c<y.c;}
}nod[maxn];
struct edge{int v,next;}e[maxn];
void adde(int a,int b){e[tot].v=b,e[tot].next=head[a];head[a]=tot++;}

void dfs(int u){
	dep[u]=dep[f[u][0]]+1;
	for(int i=1;i<=17;i++)f[u][i]=f[f[u][i-1]][i-1];
	for(int i=head[u];i;i=e[i].next){
		f[e[i].v][0]=u;
		dfs(e[i].v);
	}
}

void pre(){
	for(int i=1;i<=n*2;i++)ff[i]=i;cnt=n;
	for(int i=1;i<=m;i++){
		int dx=find(nod[i].a),dy=find(nod[i].b);
		if(dx==dy)continue;
		ff[dx]=ff[dy]=++cnt;
		val[cnt]=nod[i].c;
		adde(cnt,dx),adde(cnt,dy);
	}
	dfs(cnt);
}

int lca(int a,int b){
	if(dep[a]>dep[b])swap(a,b);
	for(int i=18;i>=0;i--)if(dep[f[b][i]]>=dep[a])b=f[b][i];
	if(a==b)return a;
	for(int i=18;i>=0;i--){
		if(f[a][i]==f[b][i])continue;
		a=f[a][i],b=f[b][i];
	}
	return f[a][0];
}

int main(){
	scanf("%d%d%d",&n,&m,&Q);
	for(int i=1;i<=m;i++)scanf("%d%d%d",&nod[i].a,&nod[i].b,&nod[i].c);
	sort(nod+1,nod+1+m);
	pre();int a,b;
	while(Q--){
		scanf("%d%d",&a,&b);
		printf("%d\n",val[lca(a,b)]);
	}
	return 0;
}


版权声明:你喜欢就好

BZOJ 3551 ONTAK2010 Peaks加强版 Kruskal重构树+可持久化线段树

题目大意:同3545 强制在线 3545题解传送门:http://blog.csdn.net/popoqqq/article/details/40660953 强制在线没法排序 启发式合并也就用不了了...
  • PoPoQQQ
  • PoPoQQQ
  • 2014年11月21日 14:40
  • 2840

【BZOJ】3732 Network 最小生成树+LCA

题目传送门 挺有意思的一道题呢……至少,最小生成树+LCA的思想就非常棒。 首先,对于所有给出的边做一遍最小生成树,删去最小生成树以外的边。 然后,将最小生成树这棵无根树转化成有根树,当然还是树的重心...
  • lyfsb
  • lyfsb
  • 2017年06月09日 20:32
  • 194

BZOJ 3732: Network(最小生成树+倍增)

题目链接 题意:给出一个图,每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少很明显最终查询的边一定是在最小生成树里面的,先跑出最小生成树,然后,可以树链剖分,也可以...
  • u013167299
  • u013167299
  • 2016年12月01日 11:47
  • 222

最小生成树-kruskal算法

Kruskal算法按照边的权重大小处理,每一次从待选边中选出最小的边,企图加入到生成树当中。但此时存在一个问题,若当前边加入生成树后存在环路,则该边废弃。一直重复这一过程,直到所有的点都已经加入生成树...
  • turingwy
  • turingwy
  • 2016年02月19日 15:36
  • 1472

最小生成树之Kruskal算法

给定一个无向图,如果它任意两个顶点都联通并且是一棵树,那么我们就称之为生成树(Spanning Tree)。如果是带权值的无向图,那么权值之和最小的生成树,我们就称之为最小生成树(MST, Minim...
  • luomingjun12315
  • luomingjun12315
  • 2015年08月18日 08:12
  • 26097

最小生成树Kruskal算法朴素版 C语言实现

最小生成树Kruskal算法朴素版 C语言实现
  • sunshineacm
  • sunshineacm
  • 2017年12月11日 22:15
  • 76

BZOJ 3732 Network —— 最小生成树 + 倍增LCA

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 图中有M条...
  • DOLFAMINGO
  • DOLFAMINGO
  • 2017年07月21日 11:02
  • 98

最小生成树——Kruskal算法(C语言版)

1,问题描述 设G=(V,E)是无向连通带权图,如果G的一个子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。生成树的各边权的总和称为该生成树的耗费,求在G的所有生成树中耗费最小的最小生成树...
  • cslgliuzezhong
  • cslgliuzezhong
  • 2014年12月04日 09:49
  • 1450

数据结构:最小生成树--Kruskal算法

Kruskal算法 求解最小生成树的另一种常见算法是Kruskal算法,它比Prim算法更直观。从直观上看,Kruskal算法的做法是:每次都从剩余边中选取权值最小的,当然,这条边不能使已有...
  • zhangxiangDavaid
  • zhangxiangDavaid
  • 2014年08月07日 11:45
  • 5018

贪婪算法-最小生成树-Kruskal算法

最小生成树是找出图中包括所有结点的联通子图,使得其所有的边的权重之和最小。 Kruskal 算法提供一种在 O(ElogV) 运行时间确定最小生成树的方案。其选择的贪心策略就是,每次都选择权重最小...
  • u010726042
  • u010726042
  • 2016年04月10日 21:47
  • 669
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【BZOJ 3732】Network kruskal树
举报原因:
原因补充:

(最多只允许输入30个字)