城市猎人

12 篇文章 0 订阅
博客探讨了城市猎人问题中,如何通过理解两点已联通时额外边的影响来构造一棵树。作者提到在这样的情况下,不再需要考虑这些边,并指出问题的关键在于寻找最长时间路径,即最近公共祖先(LCA)的概念。
摘要由CSDN通过智能技术生成

城市猎人

手玩样例发现其实如果当两个点已经联通了,那么再连一条边其实没什么用,所以可以不连这条边,然后就构造出了一棵树,然后就不会了

事 实 上 , 很 容 易 ? ? ? 想 到 这 时 候 要 找 L C A , ( 好 吧 , 我 不 太 熟 ) , 算 出 路 径 上 最 大 的 天 数 , 就 是 答 案 事实上,很容易???想到这时候要找LCA,(好吧,我不太熟),算出路径上最大的天数,就是答案 LCA

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+5;
int n,m,Q,cnt=0,fa[N],head[N],dep[N],f[N][22],l[N][22],lg[N],rt=0;
int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
struct edge{
	int link,u,v,len;
}q[N<<2];
void put(int x,int y,int len){
	q[++cnt].v=y;
	q[cnt].u=x;
	q[cnt].link=head[x];
	q[cnt].len=len;
	head[x]=cnt;
}
bool Union(int x,int y){
	int fx=find(x),fy=find(y);
	if(fx!=fy){
		fa[fx]=fy;
	    return false;
	}
	return true;
}
void dfs(int s,int fath){
	if(s!=rt) {f[s][0]=fath;}
	int t=lg[dep[s]];
	for(int i=1;i<=t;i++){f[s][i]=f[f[s][i-1]][i-1];l[s][i]=max(l[f[s][i-1]][i-1],l[s][i-1]);}
	for(int i=head[s];i;i=q[i].link){int v=q[i].v;if(v==fath) continue;dep[v]=dep[s]+1;l[v][0]=q[i].len;dfs(v,s);}
}
int lon;
int Lca(int x,int y){
     if(dep[x]<dep[y]) swap(x,y); lon=0;if(x==y) return 0;
     while(dep[x]>dep[y]){
	 lon=max(lon,l[x][lg[dep[x]-dep[y]]]);
	 x=f[x][lg[dep[x]-dep[y]]];
	 }
	 if(x==y){return lon;}
    for(int i=lg[dep[y]-1];i>=0;i--)
	if(f[x][i]!=f[y][i])lon=max(lon,l[x][i]),lon=max(lon,l[y][i]),x=f[x][i],y=f[y][i]; 
    lon=max(l[x][0],lon),lon=max(l[y][0],lon),x=f[x][0],y=f[y][0];
    return lon;
}
int main(){
	scanf("%d%d%d",&n,&m,&Q);
	for(int i=1;i<=n;i++){
		fa[i]=i;
    }
    f[1][0]=1,lg[1]=0;for(int i=2;i<=n;i++){lg[i]=lg[i>>1]+1;}
	rt=0;
	for(int i=1;i<=m;i++){
	    int now=m-i+1,td=2*now;
	    while(td<=n) {
		    if(!rt) rt=now;
	    	if(!Union(td,now)){
	    		put(now,td,i);
	    	    put(td,now,i);
			}
	    	td+=now;
	    }
	}
	dep[rt]=0;f[rt][0]=rt;l[rt][0]=N;
	dfs(rt,0);
	for(int i=1;i<=Q;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		int k=Lca(u,v);
		printf("%d\n",k);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 猎人算法是一种模拟自然界中猎物和猎人之间相互追逐的算法。猎人算法由Ahmed Amenien等人于2013年提出,其灵感来自于大自然中捕食者和被捕食者的行为。 猎人算法通过模拟猎人的行为来解决优化问题。算法中使用了一群猎人来代表解空间中的解,并通过迭代中的更新来优化目标函数。 算法中的猎人受到三个基本行为的影响:搜索、区域聚集和狩猎。搜索行为是猎人在解空间中随机搜索潜在解的操作。区域聚集行为使猎人在相似的解区域中聚集在一起,以便更好地利用局部信息。狩猎行为使猎人通过随机选择局部解以及利用全局信息来更新其位置。 具体来说,猎人算法在每次迭代中,首先根据猎人的搜索能力随机选择一个搜索点。然后,根据猎人的区域聚集能力,将猎人分成几个不同的聚类群体。接下来,每个聚类内的猎人通过选择最佳解来更新其位置。最后,根据猎人的狩猎能力,通过选择全局最优解来更新猎人群体中的一些猎人的位置。 通过不断迭代上述步骤,猎人群体逐渐向目标函数的最优解收敛。猎人算法具有一定的随机性和自适应性,能够有效地处理复杂的优化问题。 在Matlab中实现猎人算法,可以使用矩阵运算和循环结构来描述猎人的行为。根据算法的步骤,可以使用矩阵表示猎人位置和速度矩阵,并通过矩阵运算来更新猎人的位置。同时,需要使用适当的循环结构来进行多次迭代,并记录每次迭代的最优解。 总之,猎人算法是一种模拟自然界猎物和猎人的行为的优化算法。通过不断迭代搜索和优化,能够逐渐接近目标函数的最优解。在Matlab中实现猎人算法,可以通过矩阵运算和循环结构来描述猎人的行为,并使用合适的参数和迭代次数来获得较好的优化结果。 ### 回答2: 猎人算法是一种基于自然界猎人与猎物之间相互作用的优化算法。在matlab中,可以通过一些步骤来实现猎人算法。 首先,我们需要定义问题的目标函数,即需要优化的目标。然后,我们选择一组合适的初始解作为猎人的位置,并给定一定的探索范围。 接下来,我们利用目标函数评估当前解的适应度,并更新每个猎人的位置。这可以通过采用基于目标函数值的随机数生成方法来实现。同时,还需要设置合适的步伐大小,以确保搜索空间内所有的解都能被猎人搜索到。 在每次迭代中,我们可以根据当前解的适应度进行排序,并选择一定比例的猎人作为移动的对象。然后,我们可以根据一定的搜索策略来更新猎人的位置。 在整个搜索过程中,我们需要设定一定的停止准则,如最大迭代次数、收敛性判断等。当满足停止准则时,搜索过程结束,并输出最优解。 猎人算法的优点在于其搜索过程自适应性强,能够较好地适应目标函数的特性。此外,猎人算法还可以利用并行计算的思想加速搜索过程,提高搜索效率。 总之,猎人算法是一种基于自然界猎人与猎物的优化算法,在matlab中可以通过一些步骤来实现。它具有较好的搜索能力和适应性,并可以应用于多种优化问题的求解。 ### 回答3: 猎人算法是一种基于自然界中猎人——猎物关系的优化算法。猎人算法模拟了猎人在寻找猎物的过程,通过调整猎人的行为策略来达到寻找最优解的目标。 猎人算法的具体过程如下:首先,随机生成一群猎人,每个猎人有自己的位置和速度。然后,利用适应值函数来评价每个猎人的适应性,即目标函数的值。根据适应值的大小,确定每个猎人的适应度。 接下来,根据适应度大小选择猎人个体,通过更新策略来更新每个猎人的位置和速度。更新策略包括考虑个体之间的相互作用和学习,以及利用随机扰动来增加搜索的多样性。最后,根据更新后的位置和速度,重新计算适应值,不断优化全局最优解。 在Matlab中实现猎人算法,首先需要定义适应值函数,并给出目标函数的表达式。然后,通过随机生成猎人的初始位置和速度,并设置相关参数,如猎人个数、迭代次数等。利用循环迭代的方法,根据更新策略和适应值函数,不断更新猎人个体的位置和速度,直到达到停止迭代的条件。 最后,可以通过绘制适应值曲线来观察算法的收敛情况,并得到最优解的位置和值。同时,还可以尝试调整算法的参数,如猎人个数、迭代次数等,以提高算法的性能。 总之,猎人算法是一种模拟猎人与猎物之间关系的优化算法,通过不断调整猎人的位置和速度,以寻找最优解。在Matlab中,可以利用该算法来求解各种优化问题,具有一定的应用价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值