题意
一个图是平面图当且仅当所有的边两两不相交(端点除外),现在给定一个带环的图,判定它是不是平面图;多组数据
思路
考虑不在环上的边,连接两点的边无非只有两种连法,走环里面或外面,两条边如果可能会有相交部分,就只能一个走外面一个走里面,这显然可以是一个2-SAT问题
将边当作节点,一条边两个点,分别为走里面和走外面,连边跑tarjan即可
Code
#include<bits/stdc++.h>
#define N 3005
#define M 100005
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
using namespace std;
int T,n,m;
int u[M],v[M],eu[M],ev[M],cir[205][205],ci[N],f[N];
int dfn[N],low[N],c,col,color[N];
int st[N],top;
struct Edge
{
int next,to;
}edge[M<<2];int head[N],cnt;
void add_edge(int from,int to)
{
edge[++cnt].next=head[from];
edge[cnt].to=to;
head[from]=cnt;
}
template <class T>
void read(T &x)
{
char c;int sign=1;
while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
while((c=getchar())>='0'&&c<='9') x=x*10+c-48; x*=sign;
}
void init()
{
memset(cir,0,sizeof(cir));
memset(dfn,0,sizeof(dfn));
memset(color,0,sizeof(color));
memset(head,0,sizeof(head));
cnt=c=col=top=0;
}
void tarjan(int rt)
{
dfn[rt]=low[rt]=++c;
st[++top]=rt;
for(int i=head[rt];i;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[rt]=Min(low[rt],low[v]);
}
else if(!color[v]) low[rt]=Min(low[rt],dfn[v]);
}
if(dfn[rt]==low[rt])
{
color[rt]=++col;
while(st[top]!=rt) color[st[top--]]=col;
--top;
}
}
void lk()
{
int tot=0;
for(int i=1;i<=m;++i) if(!cir[u[i]][v[i]]) eu[++tot]=u[i],ev[tot]=v[i];
m=tot;
for(int i=1;i<m;++i)
{
int u1=f[eu[i]],v1=f[ev[i]];
if(u1>v1) swap(u1,v1);
for(int j=i+1;j<=m;++j)
{
int u2=f[eu[j]],v2=f[ev[j]];
if(u2>v2) swap(u2,v2);
if((u1 < u2 && u2 < v1 && v1 < v2) || (u2 < u1 && u1 < v2 && v2 < v1))
{
add_edge(i,j+m);
add_edge(i+m,j);
add_edge(j,i+m);
add_edge(j+m,i);
}
}
}
}
int main()
{
read(T);
while(T--)
{
read(n);read(m);
init();
for(int i=1;i<=m;++i) read(u[i]),read(v[i]);
for(int i=1;i<=n;++i) read(ci[i]),f[ci[i]]=i;
for(int i=1;i<n;++i) cir[ci[i]][ci[i+1]]=cir[ci[i+1]][ci[i]]=1;
cir[ci[n]][ci[1]]=cir[ci[1]][ci[n]]=1;
if(m>3*n-6) { puts("NO"); continue; }
lk();
for(int i=1;i<=m*2;++i) if(!dfn[i]) tarjan(i);
bool no=0;
for(int i=1;i<=m;++i) if(color[i]==color[i+m]) no=1;
printf(no ? "NO
" : "YES
");
}
return 0;
}