D39 2-SAT P3209 [HNOI2010] 平面图判定
D39 2-SAT P3209 [HNOI2010] 平面图判定_哔哩哔哩_bilibili



图论(十三)——平面图和对偶图_图论(十三)——平面图和对偶图-CSDN博客
P3209 [HNOI2010] 平面图判定 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N=10005; int n,m,T,x[N],y[N],id[N]; int dfn[N],low[N],stk[N],scc[N],tim,top,cnt; int head[N],idx; struct Edge{int to,ne;}e[1000005]; void add(int a,int b){ e[++idx].to=b; e[idx].ne=head[a]; head[a]=idx; } void tarjan(int x){ dfn[x]=low[x]=++tim; stk[++top]=x; for(int i=head[x];i;i=e[i].ne){ int y=e[i].to; if(!dfn[y]){ //若y尚未访问 tarjan(y); low[x]=min(low[x],low[y]); } else if(!scc[y]) //若y已访问且未处理 low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]){ //若x是SCC的根 ++cnt; for(int y=-1;y!=x;) scc[y=stk[top--]]=cnt; } } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); tim=top=cnt=idx=0; for(int i=1;i<=N;i++) head[i]=dfn[i]=stk[i]=scc[i]=0; for(int i=1;i<=m;i++) scanf("%d%d",&x[i],&y[i]); for(int i=1,x;i<=n;i++) scanf("%d",&x), id[x]=i; //保存点的序号 int flag=0; if(m>3*n-6) flag=1; //无解 else{ for(int i=1;i<=m;i++) for(int j=1;j<=m;j++){ int xi=id[x[i]],yi=id[y[i]],xj=id[x[j]],yj=id[y[j]]; if(xi>yi) swap(xi,yi); if(xj>yj) swap(xj,yj); if(xi<xj&&xj<yi&&yi<yj||xj<xi&&xi<yj&&yj<yi){ add(i,j+m); //i内j外 add(i+m,j); //i外j内 } } for(int i=1;i<=2*m;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=m;i++) if(scc[i]==scc[i+m]) flag=1; //无解 } flag?puts("NO"):puts("YES"); } }
// 并查集 O(Tm^2) #include<bits/stdc++.h> using namespace std; int read(){ int s=0; char c=getchar(); while(c<'0'||c > '9') c=getchar(); while('0'<=c && c<='9')s=s*10+(c-'0'),c=getchar(); return s; } const int N=2005; int T,n,m; int x[N<<4],y[N<<4],vis[N<<4]; int id[N]; int fa[N<<5]; int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); } bool cross(int x1,int x2,int y1,int y2){ if(x1==x2||y1==y2||x1==y2||x2==y1)return 0; if(x1<x2 && y1<y2 && x2<y1)return 1; if(x2<x1 && y2<y1 && x1<y2)return 1; return 0; } bool check(){ for(int i=1;i<=m<<1;i++)fa[i]=i; for(int i=1;i<=m;i++){ if(vis[i])continue; for(int j=1;j<=m;j++){ if(vis[j])continue; if(!cross(x[i],x[j],y[i],y[j]))continue; int ii=find(i),jj=find(j); if(ii==jj)return 0; fa[ii]=find(j+m), fa[jj]=find(i+m); } } return 1; } int main(){ T=read(); while(T--){ memset(vis,0,sizeof(vis)); n=read(),m=read(); for(int i=1;i<=m;i++) x[i]=read(),y[i]=read(); for(int i=1;i<=n;i++) id[read()]=i; if(m>3*n+6){ puts("NO"); continue; } for(int i=1,a,b;i<=m;i++){ a=id[x[i]],b=id[y[i]]; x[i]=min(a,b), y[i]=max(a,b); } for(int i=1;i<=m;i++)if(y[i]==x[i]+1||(y[i]==n&&x[i]==0))vis[i]=1; if(check())puts("YES"); else puts("NO"); } return 0; }
浙公网安备 33010602011771号