[HNOI2010]平面图判定
题意
思考
如果单独的平面图判定肯定是很麻烦的,但题目给了一个条件,此平面图存在哈密顿回路,我们将哈密顿回路画成一个圆,那么原图的边(除去哈密顿回路上的边)可以看作是该圆的弦,考虑圆中两条相交的弦 (u1,v1),(u2,v2)(u1,v1),(u2,v2) ,由于是平面图,我们可以将其中的一条翻到圆外去(但两条弦不能同时翻到圆外去,原因是如果他们在圆内相交,那么在圆外也会相交,可以画图模拟一下),我们考虑将弦视为点,把相交的弦连边,这样,平面图的判定就转为了新图的二分图判定~
要注意的一点:按照题中所给的m的范围是过不去的,但这其实是个假数据范围,平面图有一条性质是 m≤3n−6,有兴趣的同学可以去了解一下证明
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x * f;
}
const int M = 10010;
struct node{
int nxt, to;
}edge[700 * 700 * 2];
int head[M], num, col[M];
void build(int from, int to){
edge[++num].nxt = head[from];
edge[num].to = to;
head[from] = num;
}
bool dfs(int u, int color){
col[u] = color;
for(int i=head[u]; i; i=edge[i].nxt){
int v = edge[i].to;
if(col[v] == color) return 0;
if(col[v] == 0 && !dfs(v, -color)) return 0;
}
return 1;
}
bool check(int u1, int v1, int u2, int v2){
return (u1 < u2 && u2 < v1 && v1 < v2) || (u2 < u1 && u1 < v2 && v2 < v1);
}
int t, n, m;
int from[M], to[M], G[M];
void clearx(){
memset(head, 0, sizeof(head)); num = 0;
memset(col, 0, sizeof(col));
memset(G, 0, sizeof(G));
}
int main(){
t = read();
while(t --){
n = read(), m = read(); int flag = 0;
clearx();
for(int i=1; i<=m; i++){
from[i] = read(); to[i] = read();
}
for(int i=1; i<=n; i++) G[read()] = i;
if(m > 3 * n - 6){
puts("NO"); continue;
}
for(int i=1; i<=m-1; i++){
for(int j=i+1; j<=m; j++){
int u1 = G[from[i]], v1 = G[to[i]], u2 = G[from[j]], v2 = G[to[j]];
if(u1 > v1) swap(u1, v1); if(u2 > v2) swap(u2, v2);
if( check(u1, v1, u2, v2) ) build(i, j), build(j, i);
}
}
for(int i=1; i<=m; i++){
if(col[i] == 0){
if(!dfs(i, 1)){
flag = 1;
break;
}
}
}
if(!flag) puts("YES");
else puts("NO");
}
return 0;
}
总结
题目要分析清楚,某些题目可能会有坑(比如这题m的虚假范围)。有时候能把题目转换成较简单的问题(将本题平面图判定转为了二分图判定)。本题还有其他解法:并查集/2-SAT
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· C# 13 中的新增功能实操
· Ollama本地部署大模型总结
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(4)
· langchain0.3教程:从0到1打造一个智能聊天机器人
· 2025成都.NET开发者Connect圆满结束