bzoj1997 [Hnoi2010]Planar

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

 

正解:二分图染色。

画一下图就能发现,如果两条边同时在哈密顿回路里面,且相交,那么它们同时在外面也会相交。

所以我们要满足两条相交的边在回路的异侧这一条件,这显然是一个二分图,直接连边染色就行了。

还有一条,就是平面图的边数$\leq 3n-6$,如果边数超过这个就可以直接判断它不是平面图了。

 

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 #define N (705)
 6 
 7 using namespace std;
 8 
 9 struct edge{ int nt,to; }g[N*N];
10 struct E{ int u,v; }e[100005];
11 
12 int head[N],vis[N],cov[N],id[N],v[N],q[N],n,m,num,fg;
13 
14 il int gi(){
15   RG int x=0,q=1; RG char ch=getchar();
16   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
17   if (ch=='-') q=-1,ch=getchar();
18   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
19   return q*x;
20 }
21 
22 il void insert(RG int from,RG int to){
23   g[++num]=(edge){head[from],to},head[from]=num; return;
24 }
25 
26 il void bfs(RG int st){
27   RG int h=0,t=1; q[t]=st,cov[st]=vis[st]=1;
28   while (h<t){
29     RG int x=q[++h],v;
30     for (RG int i=head[x];i;i=g[i].nt){
31       v=g[i].to;
32       if (vis[v]){
33     if (!(cov[x]^cov[v])){ fg=0; return; }
34     continue;
35       }
36       q[++t]=v,vis[v]=1,cov[v]=cov[x]^1;
37     }
38   }
39   return;
40 }
41 
42 il int can(RG int i,RG int j){
43   if (id[e[i].u]>id[e[j].u]) swap(i,j);
44   return id[e[i].u]<id[e[j].u] && id[e[i].v]<id[e[j].v] && id[e[i].v]>id[e[j].u];
45 }
46 
47 il void work(){
48   n=gi(),m=gi(),fg=1,num=0,memset(head,0,sizeof(head));
49   memset(vis,0,sizeof(vis)),memset(cov,0,sizeof(cov));
50   for (RG int i=1;i<=m;++i) e[i].u=gi(),e[i].v=gi();
51   for (RG int i=1;i<=n;++i) v[i]=gi(),id[v[i]]=i;
52   if (m>3*n-6){ puts("NO"); return; }
53   for (RG int i=1;i<=m;++i)
54     if (id[e[i].u]>id[e[i].v]) swap(e[i].u,e[i].v);
55   for (RG int i=1;i<m;++i)
56     for (RG int j=i+1;j<=m;++j)
57       if (can(i,j)) insert(i,j),insert(j,i);
58   for (RG int i=1;i<=m;++i){
59     if (vis[i]) continue; bfs(i);
60     if (!fg){ puts("NO"); return; }
61   }
62   puts("YES"); return;
63 }
64 
65 int main(){
66 #ifndef ONLINE_JUDGE
67   freopen("planar.in","r",stdin);
68   freopen("planar.out","w",stdout);
69 #endif
70   RG int T=gi();
71   while (T--) work();
72   return 0;
73 }

 

posted @ 2017-12-31 19:29  wfj_2048  阅读(146)  评论(0编辑  收藏  举报