1. int stk[N],vis[N],low[N],link[N],mark[N];
  2. int top,index,id,du[N];//记录入度数
  3. int pre[N],cnt,g[N];// g 用来记录topsort后的结果
  4. int g1[N]; //用来记录缩点后的每一个点所含的点
  5.  
  6. void dfs(int s)
  7. {
  8. mark[s]=;
  9. vis[s]=index++;
  10. low[s]=vis[s];
  11. stk[top++]=s;
  12. for(int p=pre[s];p!=-;p=edge[p].next)
  13. {
  14. int v=edge[p].to;
  15. if(mark[v]==) dfs(v);
  16. if(mark[v]==) low[s]=min(low[s],low[v]);
  17. }
  18. if(low[s]==vis[s])
  19. {
  20. int tmp;
  21. id++;
  22. do
  23. {
  24. tmp=stk[top-];
  25. link[tmp]=id;
  26. mark[tmp]=-;
  27. }while(stk[--top]!=s);
  28. }
  29. }
  30.  
  31. void add_edge(int u,int v)
  32. {
  33. edge[cnt].from=u;
  34. edge[cnt].to=v;
  35. edge[cnt].next=pre[u];
  36. pre[u]=cnt++;
  37. }
  38.  
  39. void topsort()
  40. {
  41. memset(mark,,sizeof(mark));
  42. top=;
  43. int tcnt=;
  44. for(int i=;i<=id;i++)
  45. if(du[i]==)
  46. {
  47. mark[i]=;
  48. stk[top++]=i;//把这个节点入栈
  49. g[tcnt++]=i;
  50. }
  51. while(top!=)
  52. {
  53. int cur=stk[--top];
  54. for(int p=pre[cur];p!=-;p=edge[p].next)
  55. {
  56. int v=edge[p].to;
  57. if(mark[v]==) continue;
  58. du[v]--;
  59. if(du[v]==)
  60. {
  61. mark[v]=;
  62. stk[top++]=v;
  63. g[tcnt++]=v;
  64. }
  65. }
  66. }
  67.  
  68. }
  69.  
  70. void dfs1(int s) //将所有不可能的情况标记
  71. {
  72. mark[s]=-;
  73. for(int p=pre[s];p!=-;p=edge[p].next)
  74. {
  75. int v=edge[p].to;
  76. dfs1(v);
  77. }
  78. }
  79.  
  80. void sat2(int sn) //top 表示传入的点数。 其中要保证标号从0开始而且0和1是一组
  81. {
  82. top=index=id=;
  83. memset(mark,,sizeof(mark));
  84. for(int i=;i<sn;i++)
  85. if(mark[i]==)
  86. dfs(i);
  87. int flag=;
  88. for(int i=;i<sn;i+=)
  89. {
  90. if(link[i]==link[i+])
  91. {
  92. flag=;
  93. break;
  94. }
  95. }
  96. if(flag)
  97. {
  98. /* 当不可行的时候输出 */
  99. printf("bad luck\n");
  100. }
  101. else
  102. {
  103. /* 可行的时候输出 */
  104. printf("YES\n");
  105.  
  106. int tcnt=cnt;
  107. memset(g1,,sizeof(g1));
  108. cnt=;
  109. memset(pre,-,sizeof(pre));
  110. for(int i=;i<sn;i++)
  111. {
  112. g1[ link[i] ]=i;
  113. }
  114.  
  115. memset(du,,sizeof(du));
  116.  
  117. for(int i=;i<tcnt;i++)
  118. {
  119. int x=edge[i].from;
  120. int y=edge[i].to;
  121. if(link[x] != link[y])
  122. {
  123. add_edge(link[y],link[x]);//建逆图
  124. du[ link[x] ]++;
  125. }
  126. }
  127. topsort();
  128. memset(mark,,sizeof(mark));
  129.  
  130. for(int i=;i<id;i++)
  131. {
  132. if(mark[ g[i] ]!=-)//表示这个点可以选
  133. {
  134. mark[ g[i] ]=;
  135. int key=g1[ g[i] ];
  136. key=key^;
  137. key=link[key];
  138. dfs1(key);
  139. }
  140. }
  141. /* print mark[ link[i] ]==1 的表示可选的 */
  142.  
  143. }
  144. }

2-SAT求任意解模板的更多相关文章

  1. KM算法详解+模板

    http://www.cnblogs.com/wenruo/p/5264235.html KM算法用来求二分图最大权完美匹配. 本文配合该博文服用更佳:趣写算法系列之--匈牙利算法 现在有N男N女,男 ...

  2. 求任意长度数组的最大值(整数类型)。利用params参数实现任意长度的改变。

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. poj3683(2-SAT 求任意方案)

    基础的2-SAT求任意方案的题目. Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissi ...

  4. AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意两点间的最短路径)(Bellman-Ford算法判断负圈)

    题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest Path Input ...

  5. 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu Tree and Permutation 找规律+求任意两点的最短路

    Tree and Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  6. 利用arguments求任意数量数字的和/最大值/最小值

    文章地址 https://www.cnblogs.com/sandraryan/ arguments是函数内的临时数据,用完销毁,有类似于数组的操作,但不是数组. 举个栗子1:利用arguments求 ...

  7. dfs+记忆化搜索,求任意两点之间的最长路径

    C.Coolest Ski Route 题意:n个点,m条边组成的有向图,求任意两点之间的最长路径 dfs记忆化搜索 #include<iostream> #include<stri ...

  8. 算法面试题:一个List<Student>,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点!

    算法面试题:一个List,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点! 解题思路 这是群里某位小伙伴去面试碰到的面试题,从题目本身来看,面试官应该是要考察面试者对泛型 Lis ...

  9. HDOJ-2222(AC自动机+求有多少个模板串出现在文本串中)

    Keywords Search HDOJ-2222 本文是AC自动机的模板题,主要是利用自动机求有多少个模板出现在文本串中 由于有多组输入,所以每组开始的时候需要正确的初始化,为了不出错 由于题目的要 ...

随机推荐

  1. C#事件-自定义事件的使用方法(转载)

    1.声明一个委托类 public delegate SomethingChangedHandler(object sender,EventArgs e); 2.在你的类中声明一个事件绑定到该委托 pu ...

  2. xcode7 断点失效

    今天下了个别人的demo,运行发现断点不起作用,开始以为是xcode7的问题,因为自升级到xcode7后没怎么用,但后来尝试其它项目,发现是可以断点的,所以才认定不是xcode的问题,而是项目配置的问 ...

  3. SQL Server 创建和使用索引

    创建索引: (1)在SQL Server Management Studio中,选择并右击要创建索引的表,从弹出菜单中选择“设计”,打开表设计器.右键单击表设计器,从弹出菜单中选择“索引/键”命令,打 ...

  4. yum安装Apache,Mysql,PHP

    用yum安装Apache,Mysql,PHP.  用yum安装Apache,Mysql,PHP. 2.1安装Apache yum install httpd httpd-devel 安装完成后,用/e ...

  5. Atitit .linux 取回root 密码q99

    Atitit .linux 取回root 密码q99 1.1. 停止mysql1 1.2. mysqld_safe路径1 1.3. Mysql配置文件路径1 1.4. Mysql路径1 1.5. 安全 ...

  6. Yii2基础常用笔记

    表单验证规则写在model类里,例如: 通过表单输入的值给模型属性填充数据用模型对象的load方法. $model->load(Yii::$app->request->post())

  7. FileStream常用的属性和方法 (转)

    对流进行操作时要引用 using System.IO; 命名空间 FileStream常用的属性和方法: 属性: CanRead 判断当前流是否支持读取,返回bool值,True表示可以读取 CanW ...

  8. 删除Win10的自带应用

    显示 Get-AppxPackage | Select Name, PackageFullName 按关键字删除 Get-AppxPackage *camera* | Remove-AppxPacka ...

  9. 在Linux系统上查看Apache服务器的错误日志

    错误日志和访问日志文件为系统管理员提供了有用的信息,比如,为 Web 服务器排障,保护系统不受各种各样的恶意活动侵犯,或者只是进行各种各样的分析以监控 HTTP 服务器.根据你 Web 服务器配置的不 ...

  10. TCP编程,Socket通讯

    网络编程分两种,一种是TCP编程,还有一种是UDP编程(点击打开链接).而本文先讲述简单的TCP编程,Socket套接字连接通讯,实现简单的client与server之间的信息传输. 以下是clien ...