$ \rightarrow $ 戳我进BZOJ原题
Description
Input
Output
Sample Input
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
Sample Output
NO
YES
Source
Day1
题目大意
给定一张无向图以及图中的一个哈密顿回路,判断无向图是否为平面图
$ n \le 200.m \le 1000 $
题解
除去哈密顿回路( $ n $ 个点的环)之外,每条边有环内、环外两个赋值
若两条边对应环上的区间有重叠,则不能同时在环内或者环外
产生4个条件“若 $ x $ 则 $ y' $ ” “若 $ x' $ 则 $ y $ ” “ 若 $ y $ 则 $ x' $ ” “ 若 $ y' $ 则 $ x $ ”
按照 $ 2-SAT $ 模型求解即可
代码
#include
#include
#include
#include
#include
using namespace std;
#define M 10005
#define N 2005
struct edge{ int v,nxt; }e[N<<8];
int head[N],tot;
void add(int u,int v){
e[++tot].v=v; e[tot].nxt=head[u]; head[u]=tot;
}
int n,m,T,u[M],v[M],c[N],pos[N];
stacks;
int dfn[N],low[N],bel[N],tim,scc,cnt;
bool vis[N];
void tarjan(int u){
dfn[u]=low[u]=++tim; s.push(u); vis[u]=1;
for(int i=head[u];i;i=e[i].nxt)
if(!dfn[e[i].v]){
tarjan(e[i].v);
low[u]=min(low[u],low[e[i].v]);
} else if(vis[e[i].v])
low[u]=min(low[u],dfn[e[i].v]);
if(dfn[u]==low[u]){
++scc;
do{
u=s.top(); s.pop(); vis[u]=0;
bel[u]=scc;
}while(dfn[u]!=low[u]); }
}
inline bool judge(){
for(int i=1;i<=cnt;++i)
if(bel[2*i]==bel[2*i-1]) return 0;
return 1;
}
inline void init(){
memset(head,0,sizeof(head));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
cnt=tot=tim=scc=0;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
for(int i=1;i<=m;++i) scanf("%d %d",&u[i],&v[i]);
for(int i=1;i<=n;++i) scanf("%d",&c[i]);
if(m>3*n-6){ puts("NO"); continue; }
init();
for(int i=1;i<=n;++i) pos[c[i]]=i;
for(int i=1;i<=m;++i){
v[i]=pos[v[i]]; u[i]=pos[u[i]];
if(u[i]>v[i]) swap(u[i],v[i]);
if(v[i]-u[i]==1||(v[i]==n&&u[i]==1)) continue;
u[++cnt]=u[i]; v[cnt]=v[i];
}
for(int i=1;i<=cnt;++i)
for(int j=i+1;j<=cnt;++j)
if((u[i]