【51nod1743】雪之国度(最小生成树+倍增)
大致题意: 给你一张无向连通图,其中每条边的边权为这条边连接的两点的权值之差。每次询问两点之间是否存在两条不重复的路径,若存在则输出这两条路径上最大值的最小值。
大致思路
这题显然就是要让你维护边双。
我们可以先对原图求一遍最小生成树,然后再将其余非树边(按权值从小到大先排一次序)一条一条地加到图中。
对于这条边连接的两个点,我们需要对它们在树上路径进行修改。
要注意的是,对于已经修改过的,我们就不能对它进行再一次修改,因为边已经排过序,新加上的边肯定没有原来加上的边更优。
至于维护,可以采用并查集。
如果要查询,直接采用倍增法在树上乱跳求答案即可。
代码
#include<bits/stdc++.h>
#define ten(x) (((x)<<3)+((x)<<1))
#define N 100000
#define M 500000
#define LogN 20
#define INF 1000000000
#define add(x,y,z) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y,e[ee].val=z)
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)<0?-(x):(x))
using namespace std;
int n,m,ee=0,val[N+5],lnk[N+5];
struct edge
{
int from,to,nxt,val,vis;
inline friend bool operator < (edge x,edge y) {return x.val<y.val;}//按边权从小到大排序
}s[M+5],e[(N<<1)+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,Fsize,stdout),Fout[(FoutSize=0)++]=ch))
int Top,FoutSize;char ch,*A,*B,Fin[Fsize],Fout[Fsize],Stack[Fsize];
public:
inline void read(int &x) {x=0;while(!isdigit(ch=tc()));while(x=ten(x)+(ch&15),isdigit(ch=tc()));}
inline void write(int x) {if(!x) return (void)(pc('0'));while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {for(register int i=0,len=x.length();i<len;++i) pc(x[i]);}
inline void clear() {fwrite(Fout,1,FoutSize,stdout);}
}F;
class UnionFindSet//并查集
{
public:
int fa[N+5];
inline void Clear() {for(register int i=1;i<=N;++i) fa[i]=i;}
UnionFindSet() {Clear();}
inline int getfa(int x) {return fa[x]^x?fa[x]=getfa(fa[x]):x;}
inline void Union(int x,int y) {if((x=getfa(x))^(y=getfa(y))) fa[y]=x;}
}U;
class Class_MulSolver//倍增
{
public:
int Depth[N+5],fa[N+5][LogN+5],Max[N+5][LogN+5];
private:
inline void dfs(int x,int lst)//DFS遍历预处理
{
for(register int i=lnk[x];i;i=e[i].nxt)
if(e[i].to^lst) Depth[e[i].to]=Depth[fa[e[i].to][0]=x]+1,Max[e[i].to][0]=e[i].val,dfs(e[i].to,x);
}
public:
inline void DfsInit() {dfs(1,0);}
inline void MulInit() {for(register int i,j=1;j<=LogN;++j) for(i=1;i<=n;++i) fa[i][j]=fa[fa[i][j-1]][j-1],Max[i][j]=max(Max[i][j-1],Max[fa[i][j-1]][j-1]);}//预处理倍增数组
inline int get_max(int x,int y)//求树上路径最大值
{
if(Depth[x]<Depth[y]) swap(x,y);
register int i,res=0;
for(i=0;Depth[x]^Depth[y];++i) if((Depth[x]^Depth[y])&(1<<i)) res=max(res,Max[x][i]),x=fa[x][i];
if(!(x^y)) return res;
for(i=0;fa[x][i]^fa[y][i];++i);
for(--i;i>=0;--i) if(fa[x][i]^fa[y][i]) res=max(res,max(Max[x][i],Max[y][i])),x=fa[x][i],y=fa[y][i];
return max(res,max(Max[x][0],Max[y][0]));
}
}MulSolver;
int main()
{
register int i,Q,x,y;
for(F.read(n),F.read(m),F.read(Q),i=1;i<=n;++i) F.read(val[i]);
for(i=1;i<=m;++i) F.read(s[i].from),F.read(s[i].to),s[i].val=abs(val[s[i].from]-val[s[i].to]);//存边
for(sort(s+1,s+m+1),i=1;i<=m;++i) if(U.getfa(s[i].from)^U.getfa(s[i].to)) U.Union(s[i].from,s[i].to),s[i].vis=1,add(s[i].from,s[i].to,s[i].val),add(s[i].to,s[i].from,s[i].val);//建一棵最小生成树
for(U.Clear(),MulSolver.DfsInit(),i=1;i<=m;++i)//将非树边一条一条加到树上
{
if(s[i].vis) continue;//如果是树边,跳过
for(x=U.getfa(s[i].from),y=U.getfa(s[i].to);x^y;x=U.getfa(x))//如果遇到已修改过的,则结束更新过程
{
if(MulSolver.Depth[x]<MulSolver.Depth[y]) swap(x,y);//如果x比y深度小,交换
MulSolver.Max[x][0]=s[i].val,U.fa[x]=MulSolver.fa[x][0];//更新信息
}
}
for(MulSolver.MulInit();Q;--Q) F.read(x),F.read(y),(U.getfa(x)^U.getfa(y)?F.write_string("infinitely\n"):(F.write(MulSolver.get_max(x,y)),F.write_char('\n')));//用倍增法求解
return F.clear(),0;
}
【51nod1743】雪之国度(最小生成树+倍增)的更多相关文章
- [51nod1743]雪之国度
雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路. 雪之女王赋予了每一座城市不同的能量,其中第i座城市被赋予 ...
- 【JZOJ4899】【NOIP2016提高A组集训第17场11.16】雪之国度
题目描述 雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路.雪之女王赋予了每一座城市不同的能量,其中第i座城 ...
- [JZOJ4899] 雪之国度
题目描述 雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路.雪之女王赋予了每一座城市不同的能量,其中第i座城 ...
- codevs 1519 过路费 最小生成树+倍增
/*codevs 1519 过路费 最小生成树+倍增*/ #include<iostream> #include<cstdio> #include<cstring> ...
- BZOJ3732Network——kruskal重构树+倍增+LCA/最小生成树+倍增
题目描述 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 & ...
- 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集
[题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...
- 【bzoj3732】Network 最小生成树+倍增LCA
题目描述 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 & ...
- 训练指南 UVA - 11354(最小生成树 + 倍增LCA)
layout: post title: 训练指南 UVA - 11354(最小生成树 + 倍增LCA) author: "luowentaoaa" catalog: true ma ...
- 【bzoj4242】水壶 BFS+最小生成树+倍增LCA
题目描述 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入 ...
随机推荐
- React.Component(V16.8.6)
组件的生命周期 挂载 当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下: constructor() static getDerivedStateFromProps() render() ...
- C - Trailing Zeroes (III)(二分)
You task is to find minimal natural number N, so that N! contains exactly Q zeroes on the trail in d ...
- CodeForces 125D【鸽巢原理】
哇塞?开始的三个数其中两个数一定能确定一个序列.(鸽巢原理) #include <bits/stdc++.h> using namespace std; typedef long long ...
- 字符串游戏(strgame)——博弈
题目 [题目描述] pure 和 dirty 决定玩 $T$ 局游戏.对于每一局游戏,有 $n$ 个字符串,并且每一局游戏由 $K$ 轮组成.具体规则如下:在每一轮游戏中,最开始有一个空串,两者轮流向 ...
- 死磕 java同步系列之synchronized解析
问题 (1)synchronized的特性? (2)synchronized的实现原理? (3)synchronized是否可重入? (4)synchronized是否是公平锁? (5)synchro ...
- POJ2488 A Knight's Journey
题目:http://poj.org/problem?id=2488 题目大意:可以从任意点开始,只要能走完棋盘所有点,并要求字典序最小,不可能的话就impossible: 思路:dfs+回溯,因为字典 ...
- 牛客 PUBG
题目链接:点击打开链接 题目大意:跑毒,跑到安全区,每个地方有敌人,输出路线经过的最少敌人的数量:-1是起点. -2是安全区 输入 5 6 6 0 -2 3 4 2 1 2 1 2 2 8 9 7 8 ...
- FoundToday 隐私政策
FoundToday 隐私政策 本应用尊重并保护所有使用服务用户的个人隐私权.为了给您提供更准确.更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息.但本应用将以高度的勤勉.审慎义 ...
- Mac/Homebrew brew update慢的方法
Homebrew是Mac的软件包管理器,我们可以通过它安装大多数开源软件.但是在使用brew update更新的时候竟然要等待很久.猜测可能是因为brew的官方源被墙或或者响应慢.于是想到的切换Hom ...
- Eclipse进行Java web开发时,可能会出现这样的错误:The superclass javax.servlet.http.HttpServlet was not found on the Java Build Path
我们遇到的错误显示如下: 我们右击有错误提示的文件夹,如下: 我们点击”配置构建路径“,如下: 我们再点击”添加库“,如下: 我们选中上图中标出的选项,再点击下一步,如下: 我们再 ...