bzoj1997 [HNOI2010]平面图判定Planar

链接

bzoj

luogu

思路

好像有很多种方法过去。我只说2-sat

环上的边,要不在里面,要不在外边。

有的边是不能同时在里面的,可以O(m^2)的连边

但是m是10000,不过平面图内边数不得超过3*n-6,

m太大的直接NO就好了,其他的n,m是一个数量级的,直接2-sat暴力连边做就好了。



细节

双向边

是边m进行2-sat,不是点n

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=1207;
  4. int read() {
  5. int x=0,f=1;char s=getchar();
  6. for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
  7. for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
  8. return x*f;
  9. }
  10. int n,m,a[N],u[10005],v[10005],tong[N],rk[10005];
  11. struct node {int v,nxt;}e[N*N*2];
  12. int head[N],tot;
  13. map<pair<int,int >,int > Hash;
  14. void add(int u,int v) {
  15. e[++tot].v=v;
  16. e[tot].nxt=head[u];
  17. head[u]=tot;
  18. }
  19. int low[N],dfn[N],cnt,stak[N],top,vis[N],col,belong[N];
  20. void tarjan(int u) {
  21. dfn[u]=low[u]=++cnt;
  22. vis[u]=1;
  23. stak[++top]=u;
  24. for(int i=head[u];i;i=e[i].nxt) {
  25. int v=e[i].v;
  26. if(!dfn[v]) {
  27. tarjan(v);
  28. low[u]=min(low[u],low[v]);
  29. } else if(vis[v]) {
  30. low[u]=min(low[u],dfn[v]);
  31. }
  32. }
  33. if(low[u]==dfn[u]) {
  34. ++col;
  35. while(stak[top]!=u) {
  36. vis[stak[top]]=0;
  37. belong[stak[top]]=col;
  38. top--;
  39. }
  40. vis[u]=0;
  41. belong[u]=col;
  42. top--;
  43. }
  44. }
  45. void clear() {
  46. tot=cnt=col=0;
  47. Hash.clear();
  48. memset(head,0,sizeof(head));
  49. memset(low,0,sizeof(low));
  50. memset(dfn,0,sizeof(dfn));
  51. memset(rk,0,sizeof(rk));
  52. }
  53. void solve() {
  54. clear();
  55. n=read(),m=read();
  56. for(int i=1;i<=m;++i) u[i]=read(),v[i]=read();
  57. for(int i=1;i<=n;++i) a[i]=read();
  58. for(int i=2;i<=n;++i) {
  59. rk[a[i]]=i;
  60. Hash[make_pair(a[i],a[i-1])]=1;
  61. Hash[make_pair(a[i-1],a[i])]=1;
  62. }
  63. Hash[make_pair(a[1],a[n])]=1;
  64. Hash[make_pair(a[n],a[1])]=1;
  65. if(m>3*n-6) return puts("NO"),void();
  66. for(int i=1;i<=m;++i) {
  67. if(!Hash[make_pair(u[i],v[i])]) {
  68. memset(tong,0,sizeof(tong));
  69. for(int j=1,flag=0;j<=n;++j) {
  70. if(u[i]==a[j]||v[i]==a[j]) flag=flag^1;
  71. tong[j]=flag;
  72. }
  73. for(int j=i+1;j<=m;++j) {
  74. if(Hash[make_pair(u[j],v[j])]) continue;
  75. if(u[i]==v[j]||u[i]==u[j]||v[i]==v[j]||v[i]==u[j]) continue;
  76. if(tong[rk[u[j]]]^tong[rk[v[j]]]) {
  77. add(i,j+m);
  78. add(j+m,i);
  79. add(i+m,j);
  80. add(j,i+m);
  81. }
  82. }
  83. }
  84. }
  85. for(int i=1;i<=2*m;++i)
  86. if(!dfn[i])
  87. tarjan(i);
  88. for(int i=1;i<=m;++i)
  89. if(belong[i]==belong[i+m])
  90. return puts("NO"),void();
  91. return puts("YES"),void();
  92. }
  93. int main() {
  94. for(int T=read();T;T--) solve();
  95. return 0;
  96. }

bzoj1997 [HNOI2010]平面图判定Plana的更多相关文章

  1. [BZOJ1997][HNOI2010] 平面图判定

    Description Input Output     是的..BZOJ样例都没给.     题解(from 出题人): 如果只考虑简单的平面图判定,这个问题是非常不好做的. 但是题目中有一个条件— ...

  2. BZOJ1997 HNOI2010 平面图判定 planar (并查集判二分图)

    题意 判断一个存在哈密顿回路的图是否是平面图. n≤200,m≤10000n\le200,m\le10000n≤200,m≤10000 题解 如果一定存在一个环,那么连的边要么在环里面要么在外面.那么 ...

  3. P3209 [HNOI2010]平面图判定

    P3209 [HNOI2010]平面图判定 哈密尔顿环之外的任意一条边,要么连在环内部,要么连在环外部 判断两条边在同一部分会相交,则这两条边必须分开 那么把边看作点连边,跑二分图染色就行 #incl ...

  4. Luogu P3209 [HNOI2010]平面图判定(2-SAT)

    P3209 [HNOI2010]平面图判定 题意 题目描述 若能将无向图\(G=(V,E)\)画在平面上使得任意两条无重合顶点的边不相交,则称\(G\)是平面图.判定一个图是否为平面图的问题是图论中的 ...

  5. [HNOI2010]平面图判定

    Description: 若能将无向图 \(G=(V, E)\) 画在平面上使得任意两条无重合顶点的边不相交,则称 \(G\) 是平面图.判定一个图是否为平面图的问题是图论中的一个重要问题.现在假设你 ...

  6. Luogu3209 HNOI2010 平面图判定 平面图、并查集

    传送门 题意:$T$组数据,每组数据给出一个$N$个点,$M$条边,并存在一个$N$元环的图,试判断其是否为一个可平面图(如果存在一种画法,使得该图与给出的图同构且边除了在顶点处以外互相不相交,则称其 ...

  7. [HNOI2010] 平面图判定 planar

    标签:二分图判定.题解: 首先可以把题目中给你的那个环给画出来,这样就可以发现对于任意一个图来说,如果两条边要相交,就不能让他们相交,那么这两条边就要一条在里面一条在外面,如果把环画成一条链,那么就是 ...

  8. 洛谷P3209 [HNOI2010]平面图判定(2-SAT)

    传送门 看到哈密顿回路就被吓傻了……结果没有好好考虑性质…… 首先,平面图有个性质:边数小于等于$3n-6$(我也不知道为啥),边数大于这个的直接pass 然后考虑原图,先把哈密顿回路单独摘出来,就是 ...

  9. HNOI2010 平面图判定(planar)

    题目链接:戳我 我怎么知道平面图有这个性质?? 对于一个平面图,它的边数不超过点数的\(3n-6\) 所以可以直接把边数多的特判掉,剩下的图中边数和点数就是一个数量级的了. 因为这个图存在欧拉回路,所 ...

随机推荐

  1. js点击复制剪贴板

    代码用原生写的.工作中用的angular,所以如果有用angular的话,请把js代码copyToClipboard函数中的document.getElementById(elementId).inn ...

  2. HTML技巧篇:如何让单行文本以及多行文本溢出时显示省略号(…)

    参考:https://baijiahao.baidu.com/s?id=1621362934713048315&wfr=spider&for=pc 本篇文章主要给大家介绍一下在html ...

  3. VUE-002-前端分页(el-pagination)展示数据

    在web开发过程中,通常使用表格展示数据,在数据较多时采用分页的方式展示给用户. 分页方式有前端假分页和后端分页两种实现方式,此文仅记录前端假分页实现方式. 第一步:添加分页组件(el-paginat ...

  4. 自学传说中的php接口编写

    一个前端学php,感觉不可思议,但实际上面试中都会问你后台会不会.这时候php就派上用场了. 下面的是我自己百度研究的一个些心得分享一下: html代码 <!DOCTYPE html> & ...

  5. OC获取ip地址

    +(NSString *)getIp{ NSError *error;NSURL *ipURL = [NSURL URLWithString:@"http://pv.sohu.com/cit ...

  6. Java实现RSA密钥对并在加解密、加签验签中应用的实例

    一.项目结构 二.代码具体实现 1.密钥对生成的两种方式:一种生成公钥私文件,一种生成公钥私串 KeyPairGenUtil.java package com.wangjinxiang.genkey. ...

  7. 第四周Java作业

    老师说让用二维数组找最大,也就是最大和块,要求必须挨着,我其实不会写这个程序,所以我只能把自己的思路写出来 我觉得可以大问题缩小,我的思路是先把四个数一个正方形来进行计算,然后六个数矩形,把他化成两个 ...

  8. 腾讯笔试编程题,贪吃的小Q(二分查找)

    问题描述 小Q的父母要出差N天,走之前给小Q留下了M块巧克力.小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力. 输入描 ...

  9. CentOS 7下 部署Redis-cluster集群

    redis集群是一个无中心的分布式redis存储架构,可以在多个节点之间进行数据共享,解决了redis高可用.可扩展等问题,redis集群提供了以下两个好处:1)将数据自动切分(split)到多个节点 ...

  10. 利用Openssh后门 劫持root密码

    Linux操作系统的密码较难获取.而很多Linux服务器都配置了Openssh服务,在获取root权限的情况下, 可以通过修改或者更新OpenSSH代码等方法,截取并保存其SSH登录账号密码,甚至可以 ...