[Codeforces 1239D]Catowise City(2-SAT)

题面

有n个主人,每个主人都有一只猫。每个主人认识一些猫(包括自己的猫)。现在要选出一些人和一些猫,个数均大于0且总共为n,且所有人和所有猫都互不认识。判断是否有解,有解输出任意一组方案.

\(n \leq 10^6\)

分析

如果选择人i参加,那么i认识的猫一定不能参加。那么i认识的猫的主人一定要参加。这样就可以保证少了认识的猫,但是多了认识猫的主人,人数和猫数之和仍为n.

因此可以这样建图:对于人i认识的每只猫的主人j,由i向j连一条有向边,表示选了i就一定要选j。

根据2-SAT的套路,选了一个点-双联通分量中的任意一个点,那么这个v-DCC里的所有点都要被选择。

那么就可以缩点。如果只有一个v-DCC,说明没有猫被选择,不符合题意。

否则选缩点后的图里任意一个出度为0的v-DCC即可。这里面的全选人,剩下的点全选猫。

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<vector>
  6. #include<stack>
  7. #define maxn 1000000
  8. using namespace std;
  9. int t,n,m;
  10. vector<int>E[maxn*2+5];
  11. void add_edge(int u,int v){
  12. E[u].push_back(v);
  13. }
  14. int dfn[maxn*2+5];
  15. int low[maxn*2+5];
  16. stack<int>st;
  17. int cnt=0,tim=0;
  18. int bel[maxn*2+5];
  19. bool ins[maxn*2+5];
  20. vector<int>bcc[maxn*2+5];
  21. void tarjan(int x){
  22. dfn[x]=low[x]=++tim;
  23. st.push(x);
  24. ins[x]=1;
  25. for(int y : E[x]){
  26. if(!dfn[y]){
  27. tarjan(y);
  28. low[x]=min(low[x],low[y]);
  29. }else if(ins[y]){
  30. low[x]=min(low[x],dfn[y]);
  31. }
  32. }
  33. if(low[x]==dfn[x]){
  34. cnt++;
  35. int y;
  36. do{
  37. y=st.top();
  38. st.pop();
  39. ins[y]=0;
  40. bel[y]=cnt;
  41. bcc[cnt].push_back(y);
  42. }while(y!=x);
  43. }
  44. }
  45. bool is_jury[maxn*2+5];
  46. void ini(){
  47. for(int i=1;i<=n*2;i++){
  48. E[i].clear();
  49. bcc[i].clear();
  50. bel[i]=dfn[i]=low[i]=0;
  51. is_jury[i]=0;
  52. }
  53. cnt=tim=0;
  54. }
  55. int main(){
  56. int u,v;
  57. scanf("%d",&t);
  58. while(t--){
  59. scanf("%d %d",&n,&m);
  60. ini();
  61. for(int i=1;i<=m;i++){
  62. scanf("%d %d",&u,&v);
  63. if(u==v) continue;
  64. E[u].push_back(v);
  65. }
  66. for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
  67. if(cnt==1) printf("No\n");
  68. else{
  69. printf("Yes\n");
  70. printf("%d %d\n",bcc[1].size(),n-bcc[1].size());
  71. for(int x : bcc[1]) {
  72. is_jury[x]=1;
  73. printf("%d ",x);
  74. }
  75. printf("\n");
  76. for(int i=1;i<=n;i++){
  77. if(!is_jury[i]) printf("%d ",i);
  78. }
  79. printf("\n");
  80. }
  81. }
  82. }

[Codeforces 1239D]Catowise City(2-SAT)的更多相关文章

  1. Codeforces 1239D. Catowice City

    传送门 如果选择 $i$ 当陪审团成员,那么 $i$ 认识的猫一定不能参加 又因为总人数和猫数要为 $n$ ,那么 $i$ 认识的猫 的主人也一定要当陪审团成员(不然总数不够) 所以可以考虑这样构图, ...

  2. Codeforces Gym 100015C City Driving 离线LCA

    City Driving 题目连接: http://codeforces.com/gym/100015/attachments Description You recently started fre ...

  3. Codeforces 521E - Cycling City(点双连通分量+分类讨论)

    Codeforces 题面传送门 & 洛谷题面传送门 大家都是暴力找生成树然后跳路径,代码不到 50 行(暴论)的一说--好,那本蒟蒻决定提供一种代码 150 行,但复杂度也是线性的分类讨论做 ...

  4. Codeforces Round #328 (Div. 2) D. Super M 虚树直径

    D. Super M Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/592/problem/D ...

  5. Codeforces 592D - Super M - [树的直径][DFS]

    Time limit 2000 ms Memory limit 262144 kB Source Codeforces Round #328 (Div. 2) Ari the monster is n ...

  6. CodeForces - 592D: Super M(虚树+树的直径)

    Ari the monster is not an ordinary monster. She is the hidden identity of Super M, the Byteforces’ s ...

  7. 【27.66%】【codeforces 592D】Super M

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. CodeForces 821D Okabe and City

    Okabe and City 题解: 将行和列也视为一个点. 然后从普通的点走到行/列的点的话,就代表这行/列已经被点亮了. 然后将费用为0的点建上边. 注意讨论(n,m)非亮的情况下. 代码: #i ...

  9. codeforces 821 D. Okabe and City(最短路)

    题目链接:http://codeforces.com/contest/821/problem/D 题意:n*m地图,有k个位置是点亮的,有4个移动方向,每次可以移动到相邻的点亮位置,每次站在初始被点亮 ...

随机推荐

  1. 【leetcode】Monotone Increasing Digits

    Given a non-negative integer N, find the largest number that is less than or equal to N with monoton ...

  2. linux-网络管理-6

    Hub 集线器 物理层设备 多端口中继器,不记忆MAC地址 以太网桥 OSI第二层数据链路层 扩展了网络带宽 分割了网络冲突域,使网络冲突被限制在最小的范围内 交换机作为更加智能的交换设备,能够提供更 ...

  3. java总结2

    1,对象数组,必须指定了数组长度,长度是固定的 2,除了ArrayList<E>以外,类赋值给变量,只有string类拿到的是值,其他类拿到的都是类的地址值, ArrayList<E ...

  4. PHP+FLASH大文件断点续传功能分享

    1.使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc) APC实现方法: 安装APC,参照官方文档安装,可以使 ...

  5. UVa 1602 Lattice Animals (STL && 生成n连块 && 无方向形状判重)

    题意 : 给定一个 w * h 的 矩阵,在矩阵中找不同n个连通块的个数(旋转,翻转,平移算作一种) 分析 : 这题的关键点有两个 ① 生成n连块并且存储起来(因为题目是多测试用例,如果每一次都重新生 ...

  6. 指定文件或文件夹直接提交到svn指定目录

    我这里先说两种方法第一种:1.先将那个目录checkout下来2.将要添加的文件或者文件夹放到这个目录中3.右击文件执行svn菜单中的add命令4.右击文件执行svn菜单中的commit命令第二种:如 ...

  7. Linux系统安装时分区的介绍

    一般来说,在linux系统中都有最少两个挂载点,分别是/ (根目录)及 swap(交换分区),其中,/ 是必须的: 建议挂载的几大目录: /-------根目录,唯一必须挂载的目录.不要有任何的犹豫, ...

  8. vim编辑器快捷键

    光标控制命令 命令 光标移动 h或^h 向左移一个字符 j或^j或^n 向下移一行 k或^p 向上移一行 l或空格 向右移一个字符 G 移到文件的最后一行 nG 移到文件的第n行 w 移到下一个字的开 ...

  9. 关于kafka在windows上的安装、运行

    一.安装kafka    下载地址:http://kafka.apache.org/downloads 要下载Binary downloads这个类型,不要下载源文件,这种方便使用.下载后,解压放在D ...

  10. Phaser3 场景Scene之间的传值 -- HTML网页游戏开发

    一.首先当然得有至少有二个场景sceneA.js,sceneB.js 二.从场景A传值到场景B二种方法 1)通过事件this.events.emit('event key',{objKey:objVa ...