省选专练(学习)Kruskal重构树BZOJ3732: Network

论坛 期权论坛 脚本     
匿名技术用户   2020-12-30 22:09   14   0

很神奇的东西

%%%XCdalao考完试给我说:我好菜啊:我不会记录边权就开了点

%%%他考场发明了Kruskal重构树

Kruskal重构树的特点是:

由于边权的单调性于是父亲节点权值大于儿子节点

而且只有叶子节点才是真实的节点

Kruskal重构树的性质:

LCA的权就是瓶颈

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=2e5+100;
inline void read(int &x){
 x=0;
 char ch=getchar();
 int f=1;
 while(ch<'0'||ch>'9'){
  if(ch=='-')f=-1;
  ch=getchar();
 }
 while(ch>='0'&&ch<='9'){
  x=x*10+ch-'0';
  ch=getchar();
 }
 x*=f;
}
struct Front_star{
 int u,v,w,nxt;
}e[N*4];
int cnt=0;                      
int head[N]={};
void Insert(int u,int v){
 cnt++;
 e[cnt].u=u;
 e[cnt].v=v;
 e[cnt].nxt=head[u];
 head[u]=cnt;
}
int n,m;
bool cmp(Front_star A,Front_star B){
 return A.w<B.w;
}
int fa[N]={};
int tot;
int st[N][21]={};
int dep[N]={};
void dfs(int u,int fat){
// cout<<u<<" "<<fat<<'\n';
 st[u][0]=fat;
 for(int i=1;i<=18;i++){
  st[u][i]=st[st[u][i-1]][i-1];
 }
 for(int i=head[u];i;i=e[i].nxt){
  int v=e[i].v;
  if(v==fat)continue;
  dep[v]=dep[u]+1;
  dfs(v,u);
 }
}
int GetLCA(int x,int y){
 if(dep[x]<dep[y])swap(x,y);
 for(int i=20;i>=0;i--){
  if(dep[x]-(1<<i)>=dep[y])x=st[x][i];
 }
// cout<<x<<" "<<y<<'\n';
 if(x==y)return x;
 for(int i=20;i>=0;i--){
  if(st[x][i]!=st[y][i]){
   x=st[x][i];
   y=st[y][i];
  }
 }
 return st[x][0];
}
int val[N]={};
inline int getfa(int x){
 if(fa[x]==x)return x;
 else return fa[x]=getfa(fa[x]);
}
int main(){
// freopen("BZOJ3732.in","r",stdin);
 read(n);
 int K;
 tot=n;
 read(m);
 read(K);
 for(int i=1;i<=m;i++){
  read(e[i].u);
  read(e[i].v);
  read(e[i].w);
 }
 cnt=m;
 sort(e+1,e+1+m,cmp);
 for(int i=1;i<=2*n;i++)fa[i]=i;
 for(int i=1;i<=m;i++){
//  cout<<e[i].w<<'\n';
  int u=e[i].u;
  int v=e[i].v;
  if(getfa(u)!=getfa(v)){
   tot++;
   Insert(tot,getfa(u));
   Insert(tot,getfa(v));
   fa[getfa(u)]=tot;
   fa[getfa(v)]=tot;
   val[tot]=e[i].w;
  }
 }
 /*for(int i=n+1;i<=tot;i++){
  cout<<val[i]<<'\n';
 }*/
// cout<<tot<<'\n';
 dfs(tot,0);
 while(K--){
  int A,B;
  read(A);
  read(B);
//  cout<<GetLCA(A,B)<<" ";
  cout<<val[GetLCA(A,B)]<<'\n';
 }
}

转载于:https://www.cnblogs.com/Leo-JAM/p/10079200.html

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP