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
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
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 }