题目描述

题解:

这个题目要求的是把一张无向图变成一个团和一个独立集的方案数。这看似好像无从下手。那么我们可以换一个角度思考,我们考虑先求出一个解,然后通过调整得出所有解。

假设已经求出了一个解,我们会发现,其它所有的解只可能由这个解通过三种方式得到:
1.将一个原本在独立集里面的点放到团中(可行的条件下)。
2.将一个原本在团中的点放到独立集中(可行的条件下)。
3.将一个独立集中的点和团中的点交换(可行的条件下)。
意思就是,如果有属于同一组中的两个及以上的点到另一个组中,就肯定不行。

那么接下来问题就转化成了怎样求一组解。我们可以把一个点拆分成两个状态,放入团或是放入独立集中。那么我们的目标即是将这2n个状态分到两个集合中,每个集合中有n个状态,此时我们随便选择一个集合,就是一组可行解了。
那么我们就可以用2-Sat来解决。
约束条件是如果a到b有边,那么a在独立集中,b就不能在。
如果a到b无边,那么a在团中,b就不能在。
剩下的过程就是Tarjan缩点加上建反图拓扑排序一下。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn=10005;
int n;
namespace twosat{vector<int> e[maxn],a[maxn],f[maxn];bool vis[maxn];bitset<5005> hsh[5005];int tot,top,ans,inn[maxn],c[maxn],dfn[maxn],low[maxn],gr[maxn],stack[maxn],que[maxn];bool pic[maxn],pd[maxn],pd1[maxn];void nosolu(){printf("0\n"); exit(0);}void init(){scanf("%d",&n);for (int i=1;i<=n;i++){int x,y; scanf("%d",&x);for (int j=1;j<=x;j++) scanf("%d",&y),hsh[i][y]=1;for (int j=1;j<=n;j++)if (j!=i){if (hsh[i][j]) e[2*i].push_back(2*j-1);//2*i-1是团,2×i是独立集else e[2*i-1].push_back(2*j); }}if (n==2) {printf("2\n"); exit(0);}}void tarjan(int x){dfn[x]=low[x]=++tot,vis[x]=1,stack[++top]=x;for (int j=0;j<e[x].size();j++)if (!dfn[e[x][j]]) {int y=e[x][j];tarjan(y);low[x]=min(low[x],low[y]);} else if (vis[e[x][j]]) low[x]=min(low[x],dfn[e[x][j]]);if (low[x]==dfn[x]){while (stack[top]!=x) {gr[stack[top]]=x,vis[stack[top]]=0,top--;}gr[stack[top]]=x,vis[stack[top]]=0,top--;}}void tar(){for (int i=1;i<=2*n;i++) if (!dfn[i]) tarjan(i);}int get(int x){if (x%2==1) return x+1; else return x-1;}void rebuild(){for (int i=1;i<=2*n;i++) f[gr[i]].push_back(i);for (int i=1;i<=n;i++) if (gr[2*i-1]==gr[2*i]) nosolu();for (int i=1;i<=2*n;i++){for (int j=0;j<e[i].size();j++)if (gr[i]!=gr[e[i][j]]) a[gr[e[i][j]]].push_back(gr[i]),inn[gr[i]]++; e[i].clear();}}void topsort(){memset(vis,0,sizeof(vis));int head=0,tail=0;for (int i=1;i<=2*n;i++)if (!inn[i]) que[++tail]=i;while (head!=tail){head++; int u=que[head];for (int i=0;i<f[u].size();i++)if (!vis[get(f[u][i])]) pic[f[u][i]]=1,vis[f[u][i]]=1;f[u].clear();for (int i=0;i<a[u].size();i++)if (inn[a[u][i]]){int v=a[u][i]; inn[v]--;if (!inn[v]) que[++tail]=v;}a[u].clear();}}void calc(){int ans=0,sum1=0,sum2=0;for (int i=1;i<=n;i++)if (pic[2*i-1]) c[i]=1,sum1++; else c[i]=2,sum2++; //1是团,2是独立集if (sum1&&sum2) ans++;for (int i=1;i<=n;i++)if (c[i]==1){bool check=0;for (int j=1;j<=n;j++)if (hsh[i][j]&&c[j]==2) {check=1; break;}if (check==0&&(sum1-1)) ans++,pd[i]=1;} else {bool check=0;for (int j=1;j<=n;j++)if (c[j]==1&&(!hsh[i][j])) {check=1; break;}if (check==0&&(sum2-1)) ans++,pd1[i]=1;}for (int i=1;i<n;i++)for (int j=i+1;j<=n;j++)if (((pd[i]&&pd1[j])||(pd1[i]&&pd[j]))&&hsh[i][j])ans++;printf("%d\n",ans);}void solve(){init(); tar(); rebuild(); topsort(); calc();}
}
int main(){twosat::solve();return 0;
}

LOJ#2155. 「POI2011 R1」同谋者 Conspiracy相关推荐

  1. 「POI2011 R1」Conspiracy

    「POI2011 R1」Conspiracy 解题思路 : 问题转化为,将点集分成两部分,其中一部分恰好组成一个团,其中另一部分恰好组成一个独立集. 观察发现,如果求出了一个解,那么答案最多可以在这个 ...

  2. Loj #3124. 「CTS2019 | CTSC2019」氪金手游

    Loj #3124. 「CTS2019 | CTSC2019」氪金手游 题目描述 小刘同学是一个喜欢氪金手游的男孩子. 他最近迷上了一个新游戏,游戏的内容就是不断地抽卡.现在已知: - 卡池里总共有 ...

  3. LOJ#3054. 「HNOI 2019」鱼

    LOJ#3054. 「HNOI 2019」鱼 https://loj.ac/problem/3054 题意 平面上有n个点,问能组成几个六个点的鱼.(n<=1000) 分析 鱼题,劲啊. 容易想 ...

  4. LOJ 2288「THUWC 2017」大葱的神力

    LOJ 2288「THUWC 2017」大葱的神力 Link Solution 比较水的提交答案题了吧 第一个点爆搜 第二个点爆搜+剪枝,我的剪枝就是先算出 \(mx[i]\) 表示选取第 \(i \ ...

  5. loj #2509. 「AHOI / HNOI2018」排列

    #2509. 「AHOI / HNOI2018」排列 题目描述 给定 nnn 个整数 a1,a2,-,an(0≤ai≤n),以及 nnn 个整数 w1,w2,-,wn.称 a1,a2,-,an 的一个 ...

  6. LOJ 2979 「THUSCH 2017」换桌——多路增广费用流

    题目:https://loj.ac/problem/2979 原来的思路: 优化连边.一看就是同一个桌子相邻座位之间连边.相邻桌子对应座位之间连边. 每个座位向它所属的桌子连边.然后每个人建一个点,向 ...

  7. LOJ 3124 「CTS2019 | CTSC2019」氪金手游——概率+树形DP

    题目:https://loj.ac/problem/3124 看了题解:https://www.cnblogs.com/Itst/p/10883880.html 先考虑外向树. 考虑分母是 \( \s ...

  8. loj #3086. 「GXOI / GZOI2019」逼死强迫症

    背景: 好像也没什么. 题目传送门: https://loj.ac/problem/3086 题意: 给一个2∗n2*n2∗n的矩阵,现在要用2∗(n−1)2*(n-1)2∗(n−1)的矩形和222块 ...

  9. LOJ #6672. 「XXOI 2019」惠和惠惠和惠惠惠(生成函数,整式递推)

    题目 没有latex就没有推式子的动力怎么破? 设 f i , j f_{i,j} fi,j​表示在前 j j j个回合里,血量为 0 0 0了 i i i个回合且第 j j j个回合血量为 0 0 ...

  10. LOJ#3085. 「GXOI / GZOI2019」特技飞行(KDtree+坐标系变换)

    题面 传送门 前置芝士 请确定您会曼哈顿距离和切比雪夫距离之间的转换,以及\(KDtree\)对切比雪夫距离的操作 题解 我们发现\(AB\)和\(C\)没有任何关系,所以关于\(C\)可以直接暴力数 ...

最新文章

  1. 深度丨Google告诉你为什么各大机构都在争相研究AI芯片
  2. html select滚动轴,javascript - html select scroll bar - Stack Overflow
  3. 解决AJAX CalendarExtender控件不显示中文的情况(转帖博客园某人(不好意思,实在是没有找到您的尊姓大名,感谢一下!))...
  4. 《深入理解java内存模型》学习整理1
  5. 华为OJ: 公共字符串计算
  6. php声明一个类的关键字,php中怎么实例化一个类
  7. oracle 数组的用法,oracle存储过程中数组的使用
  8. centos mysql 允许远程访问
  9. mysql 查看数据库字段是否存在,mysql查询某张表是否存在某个字段和判断是否存在某个表名...
  10. 微信开发 调用摄像机拍照(录像)功能
  11. XP开通局域网共享(访问本机无需验证即可进入)
  12. mysql 事务处理null_如何使用Mysql正确的处理财务数据
  13. BZOJ4597 SHOI2016随机序列(线段树)
  14. k2ttl救砖_拆解刷breed变砖的斐讯K2P并修复
  15. 联想ThinkPad E15 2021款 酷睿版怎么样?测评值得买吗?
  16. 由公司APP大面积闪退问题引发的测试基建思考
  17. 学校计算机教室学生使用记录表,学校学生信息技术教学计划
  18. TCL发布两款可穿戴设备;中兴通讯推出第三代5G室内路由器;绘王联合制作《河岸》获棕榈泉国际短片电影节最佳动画奖 | 全球TMT...
  19. 面试前端的简历的注意事项
  20. vue 项目node服务器部署流程

热门文章

  1. Microsemi Libero系列教程(全网首发)
  2. qPCR检测基因表达的引物数据库
  3. dns被劫持有什么现象?DNS是什么 dns被劫持了如何解决
  4. Frequent values POJ - 3368(线段树)
  5. Latex论文用bibtex实现期刊/会议缩写
  6. 医院排队叫号系统源码
  7. “ODM OEM OBM的区别”网址汇总
  8. 微软经典面试题(数字翻译为中文)
  9. RGB与CMYK颜色模式调色原理
  10. FLASH抽象层(FAL)程序的应用(rt-thread)