【BZOJ 1997】[Hnoi2010]Planar

Description

Input

Output

 
找到哈密尔顿环之后找到不在哈密尔顿环上的边
这些边如果同时在里面相交那他们同时在外面也相交,所以只能一外一内,这就变成了2-SAT,判一下就好了
平面图性质 边数<=3*n-6
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 int T,n,m,timer,top,cnt,scc;
 6 int u[10005],v[10005];
 7 int c[2005],pos[2005];
 8 int head[2005],dfn[2005],low[2005],s[2005],bel[2005];
 9 bool ss[2005];
10 struct ee{int to,next;}e[1000005];
11 void ins(int u,int v){
12     e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;
13 }
14 void tarjan(int x){
15     dfn[x]=low[x]=++timer;
16     s[++top]=x;ss[x]=1;
17     for(int i=head[x];i;i=e[i].next){
18         int v=e[i].to;
19         if(!dfn[v]) {
20             tarjan(v);
21             low[x]=min(low[x],low[v]);
22         }else if(ss[v])low[x]=min(low[x],dfn[v]);
23     }
24     if(dfn[x]==low[x]){
25         int t=-1;scc++;
26         while(t!=x){
27             t=s[top--];
28             bel[t]=scc;
29             ss[t]=0;
30         }
31     }
32 }
33 bool judge(){
34     for(int i=1;i<=m;i++)
35         if(bel[2*i]==bel[2*i-1])return 0;
36     return 1;
37 }
38 int main(){
39     scanf("%d",&T);
40     while(T--){
41         memset(head,0,sizeof(head));cnt=0;
42         scc=cnt=timer=top=0;
43         memset(low,0,sizeof(low));
44         memset(dfn,0,sizeof(dfn));
45         scanf("%d%d",&n,&m);
46         for(int i=1;i<=m;i++) scanf("%d%d",&u[i],&v[i]);
47         for(int i=1;i<=n;i++) scanf("%d",&c[i]);
48         for(int i=1;i<=n;i++) pos[c[i]]=i;
49         if(m>3*n-6){puts("NO");continue;}
50         for(int i=1;i<=m;i++){
51             u[i]=pos[u[i]];v[i]=pos[v[i]];
52             if(u[i]>v[i]) swap(u[i],v[i]);
53             if(v[i]-u[i]==1||(u[i]==1&&v[i]==n)) continue;
54             u[++top]=u[i];v[top]=v[i];
55         }
56         m=top;top=0;
57         for(int i=1;i<=m;i++)
58             for(int j=i+1;j<=m;j++){
59                 if((u[i]<u[j]&&v[i]<v[j]&&v[i]>u[j])||u[j]<u[i]&&v[i]>v[j]&&v[j]>u[i]){
60                     ins(2*i-1,2*j);ins(2*j-1,2*i);
61                     ins(2*j,2*i-1);ins(2*i,2*j-1);
62                 }
63             }
64         for(int i=1;i<=2*m;i++) if(!dfn[i]) tarjan(i);
65         if(judge()) printf("YES\n");else printf("NO\n");
66     }
67 }

 

posted @ 2016-03-01 08:03  Alisahhh  阅读(438)  评论(0编辑  收藏  举报