[省选联考 2025] 图排列 题解

news/2025/10/5 15:48:05/文章来源:https://www.cnblogs.com/FloatingLife/p/19125947

[省选联考 2025] 图排列

闲话

一想到考场上自己以为直接输出最小 dfn 序就有 \(52pts\) 我就想笑。

洛谷题解区有一个码量小的分讨做法,但是因为我不想分讨所以还是选择了这个实现起来不太用脑子的做法(虽然思路很需要脑子)。

题解

跟着部分分做。

题意

先把题面翻译的人话一点:给定一张图,要求字典序最小的排列 \(p\) 满足对于 \(a<b<c<d\) 不能同时存在边 \((p_a,p_c),(p_b,p_d)\),换句话说就是按照这个排列的顺序把点排好之后不能存在在除了端点之外的地方相交的边。

显然 dfn 序一定合法,但这不一定最优。
首先我们肯定会把 \(1\) 放在第一位,然后考虑 \(1\) 的每棵子树,显然每棵子树都是占据一段连续的区间,任意两棵子树占据的位置不会相交,否则必然会出现相交的边。而两棵子树之间的顺序是任意的。
然后每棵子树就是一个独立的子问题了,我们在求出每棵子树的答案序列之后需要给这些子树分配区间,那显然就是按照第一个数从小到大排。
当然,我们在处理子问题的时候,假设处理的是 \(u\) 这棵子树,那么 \(u\) 不一定是像 \(1\) 这样放在第一个位置的,实际上 \(u\) 插在他的儿子子树之间的任意空隙都是可以的。
所以直接把 \(u\) 作为一个长度为 \(1\) 的答案序列扔进去一起排序即可。

Tip:实际上 \(u\) 子树的答案序列的第一个数一定是 \(u\) 子树中编号最小的点,但是不知道这一点也问题不大,无非就是写这档分的时候可以简单一点。

简单环

对于一个环 \(x_1,x_2,x_3,...,x_k\),环上的点在排列中的相对顺序一定是这个环的某个循环,换句话说如果我钦定了 \(x_1\) 是排列中最靠前的点,那么其他点在排列中的相对顺序只能是 \(x_2,x_3,..,x_k\) 或者 \(x_k,x_{k-1},...,x_2\)

仙人掌

会了树之后,对于一般图我们显然也希望可以套用树的做法,圆方树就可以很好地帮我们把图转换成树的形态,所以我们不妨先考虑仙人掌的情况。
首先以 \(1\) 为根建出圆方树:
对于一个圆点,他的儿子是方点,这些方点的子树同样需要满足各自占领一段连续的区间,但是子树之间是可以任意排列的,所以递归处理之后套用树的做法即可。
对于一个方点,他代表了一个点双,由于是仙人掌,这里一个点双就是一个简单环。这个环上的点就不能随便乱排了,需要满足我们上面环的要求。但是这还不够,注意到这个方点存在一个父亲圆点,这个环上的其他圆点要么全都放在这个父亲之后,要么全都放在这个父亲之前,因此这个方点的儿子总共只有两种排列方法,一种正着放,一种反着放,取一个字典序最小的即可。
注:不管这些儿子圆点是放在父亲之前还是之后,这两种放法都是合法的,所以当前方点的决策并不依赖于父亲的决策。

一般连通图

现在一个点双并不一定是一个简单环了,但是题目保证了一定有解,所以可以想到这个点双应该不会很复杂,考虑分析一下这题中点双的性质:
结论一: 这个点双不能存在同胚于 \(K_4\) 的子图。也即这个点双是广义串并联图。
证:对于下面这个 \(K_4\),显然 \(1-2-3-4\)\(1-2-4-3\) 这两个环不可能同时满足条件。

结论二: 这个点双不能存在同胚于下面这个图的子图。

证:这个图有三个环 \(1-2-3-4\)\(1-2-3-5\)\(1-4-3-5\),我们枚举第一个环在排列上的摆放方式(共有 \(8\) 种,但是 \(1,3\) 放在开头的情况对称,\(2,4\) 放在开头的情况堆成,所以只枚举 \(4\) 种):

  • \(1-2-3-4\):第二个环只能是 \(1-2-3-5\) 或者 \(5-1-2-3\),第三个环只能是 \(1-5-3-4\),显然不能同时合法。
  • \(1-4-3-2\):第二个环只能是 \(1-5-3-2\),第三个环只能是 \(1-4-3-5\) 或者 \(5-1-4-3\),显然不能同时合法。
  • \(2-3-4-1\)\(2-1-4-3\):同理,读者自证不难。

根据这两个结论可以知道这个点双形如一个圆,然后圆上有一些弦,任意两条弦不在除了顶点处相交。
所以这个点双的哈密尔顿回路存在且唯一,就是最外面的圆,这个回路同样需要满足上面简单环的限制。
我们只需要对每个点双求出哈密尔顿回路就可以套用仙人掌的做法了,一种经典求法是像广义串并联图那样每次缩二度点叠重边,然后在缩二度点的时候用链表维护哈密尔顿环,当然你也可以用 这篇题解 的做法。下面的代码里写的是前者。

一般图

我们先对每个连通块求出答案。
然后不难证明任意两个连通块在最终的答案序列上的区间要么不交,要么完全包含,即我们可以在某个连通块的答案序列中插入另一个连通块的完整的答案。
所以我们把所有连通块的答案按照第一个数排序,从第一个连通块开始填,当我即将要填的数大于下一个连通块的第一个数时,就跳到下一个连通块去做,做完了再继续填当前连通块的数。

复杂度 \(O(n)\) 或者 \(O(n\log n)\)

code
贴一下用了一堆 STL 的巨大常数代码(但是跑进 \(2s\) 还是没问题的)。

点击查看代码
#include<bits/stdc++.h>
#define Debug puts("-------------------------")
#define eb emplace_back
#define PII pair<int,int>
#define fi first
#define se second
using namespace std;
const int N=2e5+5;inline int read(){int w=1,s=0;char c=getchar();for(;c<'0'||c>'9';w*=(c=='-')?-1:1,c=getchar());for(;c>='0'&&c<='9';s=s*10+c-'0',c=getchar());return w*s;
}
int c,T,n,m;
int dfn[N],low[N],st[N],top,l[N];
bool vis[N];
vector<int> G[N],E[N];
vector<vector<int> > res;
namespace Solve{int rt,num,cnt,fa[N],mn[N];int pre[N],nxt[N],deg[N],id[N];vector<int> res,dcc[N];set<int> S[N];set<PII> lst;void init(){for(int i=1;i<=cnt;i++) dcc[i].clear();top=num=cnt=0;res.clear();}void dfs0(int u,int fa){vis[u]=true;dfn[u]=low[u]=++num,st[++top]=u;for(int v:G[u]){if(v==fa) continue;if(!dfn[v]){dfs0(v,u),low[u]=min(low[u],low[v]);if(low[v]>=dfn[u]){int x; ++cnt,E[n+cnt].clear();do{x=st[top--];dcc[cnt].eb(x),E[n+cnt].eb(x),E[x].eb(n+cnt);}while(x!=v);dcc[cnt].eb(u),E[n+cnt].eb(u),E[u].eb(n+cnt);}} else low[u]=min(low[u],dfn[v]);}}void dfs1(int u,int Fa){fa[u]=Fa;if(Fa) E[u].erase(find(E[u].begin(),E[u].end(),Fa));for(int v:E[u]) dfs1(v,u);}void solve(){if(lst.size()==2){int u=(*lst.begin()).se,v=(*lst.rbegin()).se;nxt[u]=pre[u]=v,nxt[v]=pre[v]=u;return;}int u=(*lst.begin()).se,x,y; lst.erase(lst.begin());x=*S[u].begin(),y=*S[u].rbegin();S[x].erase(S[x].find(u)),S[y].erase(S[y].find(u));if(!S[x].count(y)) S[x].insert(y),S[y].insert(x);else{lst.erase({deg[x],x}),lst.erase({deg[y],y});deg[x]--,deg[y]--,lst.insert({deg[x],x}),lst.insert({deg[y],y});}solve();if(nxt[x]==y) nxt[x]=pre[y]=u,pre[u]=x,nxt[u]=y;else pre[x]=nxt[y]=u,nxt[u]=x,pre[u]=y;}void Get_Hamiltonloop(int c){lst.clear();for(int u:dcc[c]) id[u]=c;for(int u:dcc[c]){pre[u]=nxt[u]=u,deg[u]=0,S[u].clear();	for(int v:G[u]) if(id[u]==id[v]) S[u].insert(v),deg[u]++;lst.insert({deg[u],u});}solve();int x=nxt[fa[n+c]],t=fa[n+c];dcc[c].clear(),dcc[c].eb(t);while(x!=t) dcc[c].eb(x),x=nxt[x];}void dfs2(int u){if(!E[u].size()) return mn[u]=u,void();for(int v:E[u]) dfs2(v);if(u<=n){sort(E[u].begin(),E[u].end(),[&](int x,int y){return mn[x]<mn[y];});mn[u]=min(u,mn[E[u][0]]);}else{E[u].clear();int c=u-n;if(mn[dcc[c][1]]<mn[dcc[c].back()]) for(int i=1;i<dcc[c].size();i++) E[u].eb(dcc[c][i]);else for(int i=dcc[c].size()-1;i>=1;i--) E[u].eb(dcc[c][i]);mn[u]=mn[E[u][0]];}}void dfs3(int u){if(u>n) for(int v:E[u]) dfs3(v);else{bool flag=false;for(int v:E[u]){if(mn[v]>u&&!flag) res.eb(u),flag=true;dfs3(v);}if(!flag) res.eb(u);}}vector<int> work(){init();if(G[rt].size()==0){vis[rt]=true;return {rt};}dfs0(rt,0),dfs1(rt,0);for(int i=1;i<=cnt;i++) Get_Hamiltonloop(i);dfs2(rt),dfs3(rt);return res;}
}
void Init(){res.clear();for(int i=1;i<=n;i++) G[i].clear(),E[i].clear(),vis[i]=dfn[i]=low[i]=0;
}
void work(){Init();n=read(),m=read();for(int i=1;i<=m;i++){int u=read(),v=read();G[u].eb(v),G[v].eb(u);}int cnt=0,id=0;for(int i=1;i<=n;i++) if(!vis[i]) Solve::rt=i,res.push_back(Solve::work()),l[cnt++]=0;top=0;st[++top]=id++;while(top||id<cnt){if(top==0) st[++top]=id++;int i=st[top]; while(l[i]<res[i].size()&&(id==cnt||res[i][l[i]]<res[id][0])) printf("%d ",res[i][l[i]++]);if(l[i]<res[i].size()) st[++top]=id++;else top--;}puts("");
}
signed main(){c=read(),T=read();while(T--) work();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/928427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows下安装并采用kubectl查看K8S日志

Windows下安装并采用kubectl查看K8S日志pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mo…

实用指南:UV 包管理工具:替代 pip 的现代化解决方案

实用指南:UV 包管理工具:替代 pip 的现代化解决方案pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

做网站的职位叫什么问题建一个团购网站需要多少钱

目录 在日常开发中&#xff0c;Date工具类使用频率相对较高&#xff0c;大家通常都会这样写&#xff1a;这很简单啊&#xff0c;有什么争议吗&#xff1f;格式化后出现的时间错乱。看看Java 8是如何解决时区问题的&#xff1a;在处理带时区的国际化时间问题&#xff0c;推荐使用…

做餐饮企业网站的费用wordpress主题电影

本节&#xff0c;我们将跟随数据流向讲解UEP管线中的烘培光照。 文章目录 一、URP烘培光照1. 搭建场景2. 烘培光照参数设置MixedLight光照设置&#xff1a;直观感受 Lightmapping Settings参数设置&#xff1a; 3. 我们如何记录次表面光源颜色首先我们提取出相关URP代码&#…

古典密码之凯撒密码

一、原理与历史 1.1 历史背景 凯撒密码由古罗马的盖乌斯・尤利乌斯・凯撒(Gaius Julius Caesar)所创,他在军事通信中广泛使用该密码,通常采用偏移量k=3的方式,这也是 “凯撒移位” 这一名称的由来。例如,他会把命…

vi/vim文本编辑器

Vim是从 vi 发展出来的一个文本编辑器,vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性 vi/vim 共分为三种模式: 命令模式、 输入模式、底线命令模式(末行模式) 命令模式:刚刚启动 vi/vim,便进入…

B3869 [GESP202309 四级] 进制转换-题解

题目 题目描述 $N$ 进制数指的是逢 $N$ 进一的计数制。例如,人们日常生活中大多使用十进制计数,而计算机底层则一般使用二进制。除此之外,八进制和十六进制在一些场合也是常用的计数制(十六进制中,一般使用字母 A…

LeetCode 139. 单词拆分(Word Break) - 动态规划深度解析 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

电子商务网站项目预算如何用php做电商网站

WTM系列视频教程序章文字摘要&#xff1a;“这个视频教程我列了个提纲&#xff0c;分成12部分&#xff0c;比较详细的介绍了WTM的功能和使用方法。另外还有一些我个人对于编程的理解&#xff0c;当然个人理解这部分你们就当故事听&#xff0c;不一定对&#xff0c;哈哈。”“有…

设计类电子书网站比较好的网站空间

来源&#xff1a;智造智库【导读】国家新一代人工智能发展规划中明确提出&#xff0c;发展自动驾驶汽车和轨道交通系统&#xff0c;加强车载感知、自动驾驶、车联网、物联网等技术集成和配套&#xff0c;开发交通智能感知系统&#xff0c;形成我国自主的自动驾驶平台技术体系和…

Spring Boot 应用中构建配置文件敏感信息加密解密方案

Spring Boot 应用中构建配置文件敏感信息加密解密方案pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

springcloud gateway Error creating bean with name bootstrapImportSelectorConfiguration:

springcloud gateway Error creating bean with name bootstrapImportSelectorConfiguration 修改 gateway 版本 从 2.2.1 ===> 2.1.3<!-- 引入 gateway 依赖 --><dependency><groupId>org.sprin…

做招聘网站需要哪些手续长沙大型网站建设公司

[css] 说说你对前端二倍图的理解&#xff1f;移动端使用二倍图比一倍图有什么好处&#xff1f; 二倍图是指单位面积下设备像素与css像素个数之比为 4 的位图。移动端使用二倍图可以在Retina屏幕下保真展示。个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃…

标准网站建设报价单六安在建项目和拟建项目

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的Linux】 文章目录 一&#xff0c;什么是进程地址空间&#xff1f;二&#xff0c;进程地址空间是怎么设计的&#xff1f;三&#xff0c;为什么要有进程地址空间&#xff1f; 一&#xff0c;什…

网站空间控制面板iis7.0建设网站

1、查看进程 ps axuf ---静态查看所有进程#user 用户#PID 每个进程的标识符&#xff0c;父进程为1#VSZ 虚拟内存#RSS 实际内存#pts 窗口 TTY系统启动窗口# %MEM 内存#STAT 该进程的状态&#xff0c;包括&#xff1a;S 可中断睡眠Ss 父进程S< 优先级较高SN…

网站认证必须做么网络广告策划案

移动 表、表分区、LOB字段、索引、分区索引 到另一表空间 alter table 命令移动 table, partition, lob字段alter index 命令移动 索引, 分区索引移动表π 移动表&#xff08;非分区表&#xff09;&#xff1a; alter table <schema.table> move tablespace <new tab…

郑州网站开发网站制作模板网站

Hadoop中自带的hadoop-mapreduce-examples-2.7.6.jar含有一些事例&#xff0c;本文将用pi计算圆周率。若想了解其计算原理&#xff0c;参考&#xff1a;http://thinkinginhadoop.iteye.com/blog/710847。 具体步骤如下&#xff1a; 1. 启动Hadoop 切换到Hadoop安装目录下的sb…

完整教程:PyCharm接入DeepSeek,实现高效AI编程

完整教程:PyCharm接入DeepSeek,实现高效AI编程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", …

Nginx的核心功能及实现

Nginx 核心功能与实现分析 项目概述 Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。 核…

2025焚烧炉厂家权威推荐,技术实力与市场口碑深度解析

随着环保意识的不断提升和固体废物处理需求的持续增长,焚烧炉作为一种能实现垃圾减量化、无害化处理的关键设备,在市政、工业、医疗等多个领域的应用愈发广泛。然而,当前国内焚烧炉行业呈现出品牌数量多、质量参差不…