博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P3209 [HNOI2010]平面图判定(2-SAT)
阅读量:7277 次
发布时间:2019-06-29

本文共 2672 字,大约阅读时间需要 8 分钟。

 

看到哈密顿回路就被吓傻了……结果没有好好考虑性质……

首先,平面图有个性质:边数小于等于$3n-6$(我也不知道为啥),边数大于这个的直接pass

然后考虑原图,先把哈密顿回路单独摘出来,就是一个环。对于每一条不在哈密顿回路上的边,有两种可能,一种是在环内,一种是在环外

我们用点来表示每一条边,把每一个点拆成两个分别表示这条边是在环内还是环外。对于两条边$i,j$,如果他们同时在环外或环内会交叉,那么就相当于有了约束条件,转化成一个2-SAT问题即可

至于连边,我们设$i$表示在环内,$i+m$表示在环外,如果$i,j$同在环内或环外会相交,那么连边$(i,j+m),(i+m,j),(j,i+m),(j+m,i)$,即他们永远不能同时在环内或环外

至于如果判断是否会相交,我们可以把环拆开,然后判断同在一侧是否会相交即可

1 //minamoto 2 #include
3 #include
4 #include
5 #define mem(a) (memset(a,0,sizeof(a))) 6 #define swap(x,y) (x^=y^=x^=y) 7 using namespace std; 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 9 char buf[1<<21],*p1=buf,*p2=buf;10 template
inline bool cmin(T&a,const T&b){
return a>b?a=b,1:0;}11 inline int read(){12 #define num ch-'0'13 char ch;bool flag=0;int res;14 while(!isdigit(ch=getc()))15 (ch=='-')&&(flag=true);16 for(res=num;isdigit(ch=getc());res=res*10+num);17 (flag)&&(res=-res);18 #undef num19 return res;20 }21 const int N=2e4+5,M=1e5+5;22 int head[N],Next[M],ver[M],tot;23 inline void add(int u,int v){24 ver[++tot]=v,Next[tot]=head[u],head[u]=tot;25 }26 int dfn[N],low[N],bl[N],st[N],num,cnt,top,n,m,k;27 void tarjan(int u){28 dfn[u]=low[u]=++num,st[++top]=u;29 for(int i=head[u];i;i=Next[i]){30 int v=ver[i];31 if(!dfn[v]) tarjan(v),cmin(low[u],low[v]);32 else if(!bl[v]) cmin(low[u],dfn[v]);33 }34 if(low[u]==dfn[u]) for(++cnt;st[top+1]!=u;--top) bl[st[top]]=cnt;35 }36 inline bool check(){37 for(int i=1,l=m<<1;i<=l;++i) if(!dfn[i]) tarjan(i);38 for(int i=1;i<=m;++i)39 if(bl[i]==bl[i+m]) return false;40 return true;41 }42 int rev[205],cir[205][205],E[205],eu[N],ev[N];43 void clear(){44 mem(head),mem(dfn),mem(low),mem(bl),mem(st),mem(cir);45 num=cnt=top=tot=0;46 }47 void solve(){48 clear();49 n=read(),m=read(),k=0;50 for(int i=1;i<=m;++i){51 eu[i]=read(),ev[i]=read();52 if(eu[i]>ev[i]) swap(eu[i],ev[i]);53 }54 for(int i=1;i<=n;++i){55 rev[E[i]=read()]=i;56 if(i>1){57 int u=E[i-1],v=E[i];58 u
3*n-6) return (void)(puts("NO"));62 for(int i=1;i<=m;++i)63 if(!cir[eu[i]][ev[i]]) eu[++k]=eu[i],ev[k]=ev[i];64 m=k;65 for(int i=1;i
v) swap(u,v);if(x>y) swap(x,y);69 if((u
x&&v
x&&u
y)){70 add(i,j+m),add(j,i+m),add(i+m,j),add(j+m,i);71 }72 }73 puts(check()?"YES":"NO");74 }75 int main(){76 // freopen("testdata.in","r",stdin);77 int T=read();78 while(T--) solve();79 return 0;80 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9786066.html

你可能感兴趣的文章
tomcat ssi配置及升级导致ssi include错误问题解决
查看>>
nginx使用ssl模块配置HTTPS支持
查看>>
无法远程排查思路和解决办法
查看>>
数据运营时代,如何基于AnalyticDB构建企业实时数仓?
查看>>
关于开发板用tftp下载失败分析
查看>>
React教程(六)——使用 create-react-app 快速构建 React 开发环境
查看>>
扎克伯格看好VR社交,表示十年后见分晓
查看>>
软件测试终极奥义?
查看>>
8 年后重登王座,Python 再度成为 TIOBE 年度编程语言
查看>>
从零开始学习区块链(1)
查看>>
CentOS 下JDK安装
查看>>
Junit4单元测试的基本用法
查看>>
LeanCloud云引擎相关问题
查看>>
一个简单的汉字搜索匹配示例(支持拼音、首字母简写)
查看>>
Mac配置PHP
查看>>
JavaScript中的单引号和双引号
查看>>
[连载]《C#通讯(串口和网络)框架的设计与实现》- 6.通讯控制器的设计
查看>>
用任天堂Switch运行VR?国外极客用“野路子”实现了
查看>>
致导科技:把无人机当作便携机器人来做
查看>>
Ubuntu 16.04安装Notepadqq编辑器替代Notepad++
查看>>