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