CodeForces 455C Civilization(并查集+树直径)

本文介绍了一种结合图论与并查集的数据结构算法,用于解决特定类型的树状结构问题。通过两次DFS遍历求解树的直径,并利用并查集进行集合间的合并与权值更新,实现高效查询和更新树结构中节点间最大权值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好久没有写过图论的东西了,居然双向边要开两倍空间都忘了,不过数组越界cf居然给我报MLE??这个题题意特别纠结,一开始一直不懂添加的边长是多长。。。
题意:给你一些点,然后给一些边,注意没有重边 环,接着给你两种操作:
1 x :求出 x 的集合中最长的边权值
2 x y:合并 x 的集合和 y的集合变成一个集合,并且将 x 集合中任意一个点与 y 集合中任意一个点相连,使合成的集合的任意两个点的最大权值最小,其中两个点相连的权值为1

开始边是固定的,因而建图并两次dfs遍历找树直径,但是不一定所有点是在连一起的所以要找扫一遍。
树直径:无根树中某两个点的距离的最大值,第一遍dfs,以任意一点为起点找到距离最远的点,接着以找到的点起点再来一遍dfs
接着使用并查集,合并两棵树更新权值:(ran[x]+1)/2+(ran[y]+1)/2+1(合并后 两树之间 可以形成的最大权值的最小值)

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=1<<28;
const double Pi=acos(-1.0);
const int Mod=1e9+7;
const int Max=600010;//双向边,开两倍
int fat[Max],ran[Max],vis[Max],len,ega;
int head[Max],nnext[Max],to[Max],e;
void Init(int n)
{
    e=0;
    memset(head,-1,sizeof(head));
    for(int i=0; i<=n; i++)
    {
        fat[i]=i;
        ran[i]=0;
        vis[i]=0;
    }
    return;
}
void add(int u,int v)
{
    to[e]=v;
    nnext[e]=head[u];
    head[u]=e++;
    return;
}
void dfs(int son,int fat,int now)//遍历树
{
    vis[son]=1;
    for(int i=head[son]; i!=-1; i=nnext[i])
    {
        if(to[i]!=fat)
            dfs(to[i],son,now+1);
    }
    if(len<now)//找到最远的点
    {
        len=now;
        ega=son;
    }
    return;
}
int Find(int x)
{
    if(x==fat[x])
        return fat[x];
    return fat[x]=Find(fat[x]);
}
void Union(int x,int y)
{
    int x1=Find(x);
    int y1=Find(y);
    if(x1==y1)
        return;
    if(x1>y1)//最小数字的得到权值
    {
        fat[x1]=y1;
        ran[y1]=max(ran[x1],max(ran[y1],(ran[x1]+1)/2+(ran[y1]+1)/2+1));//两棵树合并得到的最小直径
    }
    else
    {
        fat[y1]=x1;
        ran[x1]=max(ran[x1],max(ran[y1],(ran[x1]+1)/2+(ran[y1]+1)/2+1));
    }
    return;
}
int main()
{
    int n,m,q;
    int u,v,typ;
    while(~scanf("%d %d %d",&n,&m,&q))
    {
        Init(n);
        for(int i=0; i<m; i++)
        {
            scanf("%d %d",&u,&v);
            Union(u,v);
            add(u,v);
            add(v,u);
        }
        for(int i=1; i<=n; i++) //两次dfs求出树直径
        {
            if(!vis[i])
            {
                len=0;
                ega=i;
                dfs(i,i,0);
                len=0;
                dfs(ega,ega,0);
                ran[i]=len;//最小的点赋权值
            }
        }
        for(int i=0; i<q; i++)
        {
            scanf("%d",&typ);
            if(typ==1)
            {
                scanf("%d",&u);
                v=Find(u);
                printf("%d\n",ran[v]);
            }
            else
            {
                scanf("%d %d",&u,&v);
                Union(u,v);
            }
        }
    }
    return 0;
}
内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值