首页 > 其他分享 >P6765 [APIO2020] 交换城市

P6765 [APIO2020] 交换城市

时间:2024-05-13 17:31:13浏览次数:19  
标签:siz 连通 log int 交换 fav fau APIO2020 P6765

P6765 [APIO2020] 交换城市

来点简单做法,好想好写,不用 Kruskal 重构树!

尽管是 \(O(q\log m\log n)\),但是实测很快!


考虑只有一次询问,我们可以边做 Kruskal,边实时判断加入一条边以后是否可以建立关系。

首先,一个连通块之内的任意两个点一定都可以或都不可以建立关系。我们称一个内部点可以互相建立关系的连通块为好的连通块。一个好的连通块等价于连通块不为链。

我们定义 \(b_i\) 表示以 \(i\) 为祖先的连通块最早的变成好的连通块的时间,有三种情况会更改 \(b_i\):

  • 和另一个好的连通块相连了。

  • 在连通块内又加入了一条边。

  • 有一个点度数大于 \(2\)。

这个东西是好处理的。查询时每次只需要判断两个点是否在同一个好的连通块内即可。

inline void link(int u,int v,int i)
{
    ++d[u],++d[v];int fau=find(u),fav=find(v);
    if(fau==fav){if(!b[fau]) b[fau]=i;return ;}//存在环了
    if(!b[fau]&&b[fav]) b[fau]=i;//与好的连通块相连了
    if(b[fau]&&!b[fav]) b[fav]=i;//与好的连通块相连了
    if(siz[fau]>siz[fav]) swap(u,v),swap(fau,fav);//按秩合并
    tim[fau]=i,fa[fau]=fav,siz[fav]+=siz[fau];
    if((d[u]>2||d[v]>2)&&!b[fav]) b[fav]=i;//有点度数大于 2 了
}

对于多次询问,我们肯定不能直接做,所以考虑二分答案。但这样就要求我们记录下每次加入边后的并查集数组。

一个 naive 的想法是用主席树维护,并查集还要按秩合并,再加一个二分,然后直逼三 \(\log\)。

后来发现既然都按秩合并了,干脆不路径压缩,这样每个 \(fa_i\) 只会更改一次,记录一下更改的时间,这样查询历史版本的父亲时,只需要判断是在更改前还是更改后就行了,这样就是双 \(\log\) 了。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=1e5+10,MAXM=2e5+10;
int n,m,fa[MAXN],tim[MAXN],siz[MAXN],d[MAXN],b[MAXN];
struct node{int u,v,w;}p[MAXM];
inline int F(int x,int i){return (!tim[x]||i<tim[x])?x:fa[x];}
inline bool cmp(node x,node y){return x.w<y.w;}
inline int find(int x){return (fa[x]==x)?x:find(fa[x]);}
inline void link(int u,int v,int i)
{
    ++d[u],++d[v];int fau=find(u),fav=find(v);
    if(fau==fav){if(!b[fau]) b[fau]=i;return ;}
    if(!b[fau]&&b[fav]) b[fau]=i;
    if(b[fau]&&!b[fav]) b[fav]=i;
    if(siz[fau]>siz[fav]) swap(u,v),swap(fau,fav);
    tim[fau]=i,fa[fau]=fav,siz[fav]+=siz[fau];
    if((d[u]>2||d[v]>2)&&!b[fav]) b[fav]=i;
}
void init(int N,int M,vector <int> u,vector <int> v,vector<int> w)
{
    n=N,m=M;for(int i=0;i<m;++i) p[i+1]={u[i]+1,v[i]+1,w[i]};
    sort(p+1,p+1+m,cmp);
    for(int i=1;i<=n;++i) fa[i]=i,siz[i]=1;
    for(int i=1;i<=m;++i) link(p[i].u,p[i].v,i);
}
inline bool Check(int x,int y,int i)
{
    for(int fa=F(x,i);fa!=x;) x=fa,fa=F(x,i);
    for(int fa=F(y,i);fa!=y;) y=fa,fa=F(y,i);
    return (x==y&&b[x]&&b[x]<=i);
}
int getMinimumFuelCapacity(int x,int y)
{
    ++x,++y;int l=1,r=m;
    if(!Check(x,y,m)) return -1;
    while(l<r)
    {
        int mid=(l+r)>>1;
        Check(x,y,mid)?r=mid:l=mid+1;
    }return p[l].w;
}

顺便提一嘴,如果允许离线的话可以一起二分,\(\log\) 层每次都从头跑一遍 Kruskal,这样并查集可以路径压缩,把并查集复杂度忽略的话就到单 \(\log\) 了。虽然本来就有单 \(\log\) 在线做法。

标签:siz,连通,log,int,交换,fav,fau,APIO2020,P6765
From: https://www.cnblogs.com/int-R/p/18189662/P6765

相关文章

  • 华为S5700交换机配下链路聚合
    学习目标  ·掌握接口速率的配置方法·掌握使用手动模式配置链路聚合的方法·掌握使用静态LACP模式配置链路聚合的方法·掌握在静态LACP模式下配置接口优先级的方法 拓扑图   图4.1以太网链路聚合拓扑图 场景 您是公司的网络管理员。现在公司购买了两......
  • 代码随想录算法训练营第四天 | 23.两l两交换链表中的节点 19.删除链表的倒数第N个节点
    23.两两交换链表中的两个节点题目链接文章讲解视频讲解时间复杂度o(n)空间复杂度o(1)tips:画图,并将每一步操作用伪代码写出来,然后将代码理顺可以避免修改代码的麻烦初始化的时候就要将previous初始化为current的前一个节点,这样可以保证循环的第一步满足循环要求cla......
  • 代码随想录算法训练营第第二天 | 24. 两两交换链表中的节点 、19.删除链表的倒数第N
    两两交换链表中的节点用虚拟头结点,这样会方便很多。本题链表操作就比较复杂了,建议大家先看视频,视频里我讲解了注意事项,为什么需要temp保存临时节点。题目链接/文章讲解/视频讲解:https://programmercarl.com/0024.两两交换链表中的节点.html/***Definitionforsingly-li......
  • 排序 - 插入 & 交换 & 选择 & 堆 & 基数
    插入排序直接插入排序算法描述将一条记录插入到有序表中,得到新的有序表。将需要调整位置的元素暂存在r[0]处,然后再进行插入。算法实现voidInsertSort(SqList&L){for(i=2;i<=L.length;i++)if(L.r[i].key<L.r[i-1].key){L.r[0]=L.......
  • 新能源行业网间数据交换,更好用更专业的工具是什么?
    新能源行业涵盖了多个方面,包括但不限于新能源汽车、可再生能源技术等。新能源行业发展具有重要的意义,新能源企业的研发数据极其重要,为了保障网络安全和数据安全,许多新能源企业采用逻辑隔离的方式进行网络隔离,此时,则产生网间数据交换需求。常用的网间数据交换方式有:U盘或硬盘传......
  • 如何在保证企业研发数据安全的同时,提升交换效率?
    企业研发数据对企业而言具有至关重要的意义,如半导体IC设计、生物制药、科研单位等,研发数据就是其最核心的数据资产,研发成果就是其生命力的根本。企业⼀般通过使⽤FTP应⽤、U盘等移动介质、邮件等方式,进行数据的传输,但存在一定的安全隐患:1、FTP传输:FTP明文传输,传输不加密,容易被......
  • 华为交换机的基本查询命令
    displayiprouting-table该命令用于显示交换机的路由表信息。通过该命令,管理员可以查看交换机的路由表,包括默认路由、静态路由、动态路由等。displayinterfacebrief该命令用于显示交换机接口的基本信息。通过该命令,管理员可以查看交换机接口的状态、IP地址、子网掩码等......
  • 华三交换机做镜像口
    华三交换机的镜像口查询可以通过以下步骤进行:1进入系统视图模式,相当于配置模式,可以使用命令 system-view。查看当前的配置情况,可以使用命令 displaycurrent-configuration。进入以太网接口,可以使用命令 interfaceEthernet1/0/1。打开以太网端口,可以使......
  • 交换机基础及stp
    一、交换机基础交换机工作在数据链路层,转发数据帧,隔绝了以太网层的冲突域1、泛洪未知单播泛洪广播数据2、转发根据mac地址表进行转发3、丢弃收到的arp请求中的目的mac地址是发起的接口,则会丢弃二、stp(生成树协议) 环路引起广播风暴,网络中的主机会受到重复数......
  • BCM53161XUB0KLFBG、BCM53161XMB0KLFBG、BCM53161XMB0ILFBG: 超低功耗2.5GE交换机介绍
    产品介绍BCM5316X超低功耗2.5GE交换机设计用于SMB、工业和服务提供商市场中的多GE应用。BCM5316X交换机支持四个2.5GESGMII+端口、两个2.5GE/10GEXFI/SFI端口以及多达八个带集成GPHY的10/100/1000Base-T端口。BCM5316X交换机采用28nmRoboSwitch™架构(也称为Robo-2)。BCM5316X集......