[HNOI2010]平面图判定
Description:
若能将无向图 \(G=(V, E)\) 画在平面上使得任意两条无重合顶点的边不相交,则称 \(G\) 是平面图。判定一个图是否为平面图的问题是图论中的一个重要问题。现在假设你要判定的是一类特殊的图,图中存在一个包含所有顶点的环,即存在哈密顿回路。输入输出格式输入格式:
输入文件的第一行是一个正整数 \(T\),表示数据组数 (每组数据描述一个需要判定的图)。接下来从输入文件第二行开始有 \(T\) 组数据,每组数据的第一行是用空格隔开的两个正整数 \(N\) 和 \(M\),分别表示对应图的顶点数和边数。紧接着的 \(M\) 行,每行是用空格隔开的两个正整数 \(u\) 和 \(v\) \(\left(1\leq u,v\leq N\right)\),表示对应图的一条边 \(\left(u,v\right)\), 输入的数据保证所有边仅出现一次。每组数据的最后一行是用空格隔开的 \(N\) 个正整数,从左到右表示对应图中的一个哈密顿回路:\(V_1,V_2,…,V_N\),即对任意 \(i\not=j\) 有 \(V_i\not=V_j\) 且对任意 \(1\leq i\leq N-1\) 有 \(\left(V_i,V_i-1\right)\in E\) 及 \(\left(V_1,V_N\right)\in E\)。
输入的数据保证 \(100\%\) 的数据满足 \(T\leq100,3\leq N\leq200,M\leq10000\).
Solution:
即判断是否可以让这些边都不相交
对于环上的四个点,设它们的序号依次为 \(a_1,a_2,a_3,a_4\)
若两条边为 \(a_1-a_2\) 和 \(a_3-a_4\)
显然他们不会相交
若为 \(a_1-a_3\) 和 \(a_2-a_4\)
则只有当一条边在回路外,一条边在回路内时,方可不相交
这样,\(2-SAT\)的模型就建出来了
详见代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=1e6+5;
int n,m,T,p,tot,cnt,col;
int c[mxn],x[mxn],y[mxn],hd[mxn],ex[mxn],ey[mxn],bl[mxn],vis[mxn],dfn[mxn],ins[mxn],low[mxn],cir[mxn],f[2000][2000];
stack<int > st;
inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline void chkmax(int &x,int y) {if(x<y) x=y;}
inline void chkmin(int &x,int y) {if(x>y) x=y;}
struct ed {
int to,nxt;
}t[mxn];
inline void add(int u,int v) {
t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
}
void tj(int u)
{
dfn[u]=low[u]=++p; st.push(u); ins[u]=1;
for(int i=hd[u];i;i=t[i].nxt) {
int v=t[i].to;
if(!dfn[v]) tj(v),chkmin(low[u],low[v]);
else if(ins[v]) chkmin(low[u],dfn[v]);
}
if(low[u]==dfn[u]) {
++col;
do {
bl[u]=col; u=st.top();
st.pop(); ins[u]=0;
} while(low[u]!=dfn[u]);
}
}
int check() {
for(int i=1;i<=m*2;++i)
if(!dfn[i]) tj(i);
for(int i=1;i<=m;++i)
if(bl[i]==bl[i+m]) return 0;
return 1;
}
void solve()
{
cnt=tot=col=p=0; int a,b;
memset(hd,0,sizeof(hd));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(bl,0,sizeof(bl));
memset(f,0,sizeof(f));
n=read(); m=read();
for(int i=1;i<=m;++i) {
x[i]=read(); y[i]=read();
if(x[i]>y[i]) swap(x[i],y[i]);
}
for(int i=1;i<=n;++i) {
c[i]=read(); vis[c[i]]=i;
if(i>1) {
int a=c[i-1],b=c[i];
if(a<b) f[a][b]=1;
else f[b][a]=1;
}
}
if(m>3*n-6) {
puts("NO"); //这里是一个结论,若不满足则直接判掉
return ; //由于我太菜了,所以不会证明
}
a=c[n],b=c[1];
if(a<b) f[a][b]=1;
else f[b][a]=1;
for(int i=1;i<=m;++i) {
if(f[x[i]][y[i]]) continue ; //是环上的边,就不管它
ex[++tot]=x[i],ey[tot]=y[i];
}
m=tot; int u,v,w,z;
for(int i=1;i<m;++i) {
for(int j=i+1;j<=m;++j) {
u=vis[ex[i]],v=vis[ey[i]],w=vis[ex[j]],z=vis[ey[j]];
if(u>v) swap(u,v); if(w>z) swap(w,z);
if((u<w&&v>w&&v<z)||(u>w&&u<z&&v>z)) {
add(i,j+m); add(i+m,j); //连边
add(j,i+m); add(j+m,i); //内->外 外->内
}
}
}
printf(check()?"YES\n":"NO\n");
}
int main()
{
T=read();
while(T--) solve();
return 0;
}
[HNOI2010]平面图判定的更多相关文章
- bzoj1997 [HNOI2010]平面图判定Plana
bzoj1997 [HNOI2010]平面图判定Planar 链接 bzoj luogu 思路 好像有很多种方法过去.我只说2-sat 环上的边,要不在里面,要不在外边. 有的边是不能同时在里面的,可 ...
- P3209 [HNOI2010]平面图判定
P3209 [HNOI2010]平面图判定 哈密尔顿环之外的任意一条边,要么连在环内部,要么连在环外部 判断两条边在同一部分会相交,则这两条边必须分开 那么把边看作点连边,跑二分图染色就行 #incl ...
- Luogu P3209 [HNOI2010]平面图判定(2-SAT)
P3209 [HNOI2010]平面图判定 题意 题目描述 若能将无向图\(G=(V,E)\)画在平面上使得任意两条无重合顶点的边不相交,则称\(G\)是平面图.判定一个图是否为平面图的问题是图论中的 ...
- [BZOJ1997][HNOI2010] 平面图判定
Description Input Output 是的..BZOJ样例都没给. 题解(from 出题人): 如果只考虑简单的平面图判定,这个问题是非常不好做的. 但是题目中有一个条件— ...
- Luogu3209 HNOI2010 平面图判定 平面图、并查集
传送门 题意:$T$组数据,每组数据给出一个$N$个点,$M$条边,并存在一个$N$元环的图,试判断其是否为一个可平面图(如果存在一种画法,使得该图与给出的图同构且边除了在顶点处以外互相不相交,则称其 ...
- [HNOI2010] 平面图判定 planar
标签:二分图判定.题解: 首先可以把题目中给你的那个环给画出来,这样就可以发现对于任意一个图来说,如果两条边要相交,就不能让他们相交,那么这两条边就要一条在里面一条在外面,如果把环画成一条链,那么就是 ...
- 洛谷P3209 [HNOI2010]平面图判定(2-SAT)
传送门 看到哈密顿回路就被吓傻了……结果没有好好考虑性质…… 首先,平面图有个性质:边数小于等于$3n-6$(我也不知道为啥),边数大于这个的直接pass 然后考虑原图,先把哈密顿回路单独摘出来,就是 ...
- BZOJ1997 HNOI2010 平面图判定 planar (并查集判二分图)
题意 判断一个存在哈密顿回路的图是否是平面图. n≤200,m≤10000n\le200,m\le10000n≤200,m≤10000 题解 如果一定存在一个环,那么连的边要么在环里面要么在外面.那么 ...
- HNOI2010 平面图判定(planar)
题目链接:戳我 我怎么知道平面图有这个性质?? 对于一个平面图,它的边数不超过点数的\(3n-6\) 所以可以直接把边数多的特判掉,剩下的图中边数和点数就是一个数量级的了. 因为这个图存在欧拉回路,所 ...
随机推荐
- 总结Java虚拟机内存区域模型
本篇文章主要来总结一下Java虚拟机内存的各个区域,以及这些区域的作用.服务对象以及其中可能产生的问题,作为大家的面试宝典. 首先我们来看一下Java运行时的数据区域,Java虚拟机在执行Java程序 ...
- js 压缩上传的图片方法(默认上传的是file文件)
//压缩图片方法 function compressImg(file,callback){ var src; var fileSize = parseFloat(parseInt(file['size ...
- webpack学习笔记--配置output
Output output 配置如何输出最终想要的代码. output 是一个 object ,里面包含一系列配置项,下面分别介绍它们. filename output.filename 配置 ...
- RPC服务超时排查思路
RPC服务超时排查思路- 1.查看服务提供者日志相关信息进行排查- 2.查看消费者的超时时间设置是否合理- 3.查看服务提供者业务逻辑是否有DB操作,有的话看是否有慢SQL- 4.查看服务提供者业务逻 ...
- codeforces div2 C题思路训练【C题好难,我好菜】
1017C The Phone Number: 构造数列使得LIS和LDS的和最小,定理已知LIS=L,LDS=n/L的向上取整,根据样例可以得到设置L=根号n,构造方法如样例 截断法构造,不用考虑边 ...
- POJ 2987 Firing【最大权闭合图-最小割】
题意:给出一个有向图,选择一个点,则要选择它的可以到达的所有节点.选择每个点有各自的利益或损失.求最大化的利益,以及此时选择人数的最小值. 算法:构造源点s汇点t,从s到每个正数点建边,容量为利益.每 ...
- 【BZOJ4712】洪水
题解: 注意题目说了每个点的权值只能增加 每个点的dp方程比较简单 min(v[i],sum[i]) 那么我们考虑如果v[i]增加那么上面使用sum[i]的会带来影响 暴力的做就是一个个往上查然后修改 ...
- 【CF724F】Uniformly Branched Trees
题意:询问n个点的每个非叶子点度数恰好等于d的不同构的无根树的数目. n≤1000,d≤10n≤1000,d≤10. 题解: 这题真的是一道非常好的题 首先考虑有根树 定义f[i][j][k]表示i个 ...
- day4.字符串练习题
有变量 name = “alex leNb”,完成如下操作 1. 移除name变量对应的值两边的空格,并输出处理结果 print(name.strip()) 2. 移除name变量左边的’al’并输出 ...
- 基于Fragment的插件化
--<摘自android插件化开发指南> 1.有些项目,整个app只有一个Activity,切换页面全靠Fragment,盛行过一时,但有点极端 2.Activity切换fragment页 ...