洛谷P3209 [HNOI2010]PLANAR(2-SAT)
时间:2022-05-08
本文章向大家介绍洛谷P3209 [HNOI2010]PLANAR(2-SAT),主要内容包括题目描述、输入输出格式、输入输出样例、说明、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
题目描述
若能将无向图G=(V,E)画在平面上使得任意两条无重合顶点的边不相交,则称G是平面图。判定一个图是否为平面图的问题是图论中的一个重要问题。现在假设你要判定的是一类特殊的图,图中存在一个包含所有顶点的环,即存在哈密顿回路。
输入输出格式
输入格式:
输入文件的第一行是一个正整数T,表示数据组数(每组数据描述一个需要判定的图)。接下来从输入文件第二行开始有T组数据,每组数据的第一行是用空格隔开的两个正整数N和M,分别表示对应图的顶点数和边数。紧接着的M行,每行是用空格隔开的两个正整数u和v(1<=u,v<=n),表示对应图的一条边(u,v),输入的数据保证所有边仅出现一次。每组数据的最后一行是用空格隔开的N个正整数,从左到右表示对应图中的一个哈密顿回路:V1,V2,…,VN,即对任意i≠j有Vi≠Vj且对任意1<=i<=n-1有(Vi,Vi-1) ∈E及(V1,Vn) ∈E。输入的数据保证100%的数据满足T<=100,3<=N<=200,M<=10000。
输出格式:
包含T行,若输入文件的第i组数据所对应图是平面图,则在第i行输出YES,否则在第i行输出NO,注意均为大写字母
输入输出样例
输入样例#1:
2
6 9
1 4
1 5
1 6
2 4
2 5
2 6
3 4
3 5
3 6
1 4 2 5 3 6
5 5
1 2
2 3
3 4
4 5
5 1
1 2 3 4 5
输出样例#1:
NO
YES
说明
感谢@hibiki 对题目进行修正
如果你会做POJ3207的话,那么这道题就是道大水题
不过平面图有一个性质
边数<=点数*3-6
因此可以通过这个性质把数据规模降至O(n)
设i表示边i在圆内,i'表示i在圆外
若(i,j)在圆内相交,那么它们在圆外也一定相交
如果边i,j在圆内相交
那么就从i连向j'(i内j外),从j'连向i(i内j外),从j连向i'(j内i外),从i'连向j(j内i外)
写错了一个字母调了半个小时
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
#include<queue>
#include<iostream>
#define Pair pair<int,int>
#define F first
#define S second
using namespace std;
const int MAXN=1e6+10;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
char buf[1<<20],*p1=buf,*p2=buf;
inline int read()
{ char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct node
{
int u,v,nxt;
}edge[MAXN];
int head[MAXN],num=1;
inline void AddEdge(int x,int y)
{
edge[num].u=x;
edge[num].v=y;
edge[num].nxt=head[x];
head[x]=num++;
}
int happen[MAXN];
int dfn[MAXN],low[MAXN],tot,color[MAXN],colornum=0,vis[MAXN];
stack<int>s;
int N,M;
Pair P[MAXN];
void tarjan(int now)
{
dfn[now]=low[now]=++tot;
s.push(now);
vis[now]=1;
for(int i=head[now];i!=-1;i=edge[i].nxt)
{
if(!dfn[edge[i].v])
tarjan(edge[i].v),low[now]=min(low[now],low[edge[i].v]);
else if(vis[edge[i].v]) low[now]=min(low[now],dfn[edge[i].v]);
}
if(dfn[now]==low[now])
{
int h;colornum++;
do
{
h=s.top();s.pop();
vis[h]=0;
color[h]=colornum;
}while(h!=now);
}
}
void pre()
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(head,-1,sizeof(head));
memset(color,0,sizeof(color));
memset(happen,0,sizeof(happen));
memset(vis,0,sizeof(vis));
num=1;
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#else
#endif
int QWQ=read();
while(QWQ--)
{
pre();
N=read();M=read();
for(int i=1;i<=M;i++)
P[i].F=read(),P[i].S=read();
for(int i=1;i<=N;i++)
{
int p=read();
happen[p]=i;
}
if(M>3*N-6){printf("NOn"); continue;}
for(int i=1;i<=M;i++)
{
P[i].F=happen[P[i].F];
P[i].S=happen[P[i].S];
if(P[i].F>P[i].S) swap(P[i].F,P[i].S);
}
for(int i=1;i<=M;i++)
for(int j=i+1;j<=M;j++)
if((P[i].S>P[j].F&&P[i].F<P[j].F&&P[i].S<P[j].S)
||(P[i].F>P[j].F&&P[i].S>P[j].S&&P[i].F<P[j].S))
AddEdge(i,j+M),
AddEdge(j+M,i),
AddEdge(j,i+M),
AddEdge(i+M,j);
for(int i=1;i<=2*M;i++)
if(!dfn[i])
tarjan(i);
int flag=1;
for(int i=1;i<=2*M;i++)
if(color[i]==color[i+M])
{printf("NOn");flag=0;break;}
if(flag==1) printf("YESn");
}
return 0;
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- leetcode栈之用队列实现栈
- 3分钟短文:无私分享!Laravel模型使用2个小技巧
- 抖音小程序基础之 如何绑定点击事件(教程含源码)
- 抖音小程序基础之 如何使用内联样式 style和class(教程含源码)
- 抖音小程序基础之 如何使用选择器class id element (教程含源码)
- 3分钟短文:Laravel模型作用域,为你“节省”更多代码
- Pytorch 0.4.0版本保存的模型在高版本调用问题的解决方式
- Qt音视频开发27-Onvif设备搜索
- 容器化 FRP 使用方案
- 学习从拥有一支好笔开始
- leetcode栈之最小栈
- Discourse 安装防火墙的配置如何让邮件能够发送
- CentOS 8 如何安装 htop
- Discourse 重复安装过程中的密钥签发问题
- Appium之「元素定位和UiAutomator表达式」