题意

给出一张图,将其分为一个团和一个独立集。问有多少种方案。团和独立集都不能为空

思路

先考虑找可行方案应该怎么做

显然是个\(2-sat\)。可以将分到团和独立集中分别看为0和1。

如果两个点之间右边,那么必定不能同时在独立集中。如果两个点之间没有边,那么必定不能同时在团中。然后连边\(求2-sat\)即可

然后考虑统计方案

可以发现,如果在某个可行方案中两个点都在团中,那么在所有方案中必定不能同时在独立集中。同样,如果两个点在某个个可行方案中都在独立集中,那么在所有方案中必定不能同时出现在团中。

这说明,一个可行方案调整到另一个可行方案时,最多有一个点从团中到了独立集中。也最多有一个点,从独立集中到了团中。

我们可以通过对上面的可行方案进行调整得到所有方案。

注意题目中要求团和独立集都不能为空

代码

/*
* @Author: wxyww
* @Date:   2019-05-02 14:03:51
* @Last Modified time: 2019-05-02 15:35:29
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 5010;
#define ote(x) x > n ? x - n : x + n
ll read() {ll x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;
}
vector<int>e[N << 1],tmp[N],C[2];
int n,a[N][N];
int val[N << 1],dfn[N << 1],low[N << 1],tot,vis[N << 1],sta[N << 1],top,coljs,col[N << 1];
void tarjan(int u) {int k = e[u].size();dfn[u] = low[u] = ++tot;vis[u] = 1;sta[++top] = u;for(int i = 0;i < k;++i) {int v = e[u][i];if(!dfn[v]) {tarjan(v);low[u] = min(low[u],low[v]);} else if(vis[v]) low[u] = min(low[u],low[v]);}if(dfn[u] == low[u]) {++coljs;do {int x = sta[top--];col[x] = coljs;vis[x] = 0;}while(sta[top + 1] != u);}
}
int main() {n = read();for(int i = 1;i <= n;++i)for(int j = 1,x = read();j <= x;++j) a[i][read()] = 1;for(int i = 1;i <= n;++i) {for(int j = i + 1;j <= n;++j) {if(a[i][j]) {e[i].push_back(j + n);e[j].push_back(i + n);}else {e[i + n].push_back(j);e[j + n].push_back(i);}}}for(int i =  1;i <= n + n;++i) if(!dfn[i])  tarjan(i);for(int i = 1;i <= n;++i) if(col[i] == col[i + n]) {puts("0");return 0;}for(int i = 1;i <= n;++i) {val[i] = col[i] < col[ote(i)];//0为团中,1为独立集中C[val[i]].push_back(i);}for(int i = 1;i <= n;++i) {for(int j = 1;j <= n;++j) {if(val[i] == val[j]) continue;if(val[i] ^ a[i][j]) tmp[i].push_back(j);}}int k1 = C[0].size(),k2 = C[1].size();int ans = k1 && k2;for(int i = 0;i < k1;++i) {int x = C[0][i],z1 = tmp[x].size();if(z1 > 1) continue;for(int j = 0;j < k2;++j) {int y = C[1][j],z2 = tmp[y].size();if(z2 > 1) continue;if((!z1 && !z2) || (!z1 && tmp[y][0] == x) || (!z2 && tmp[x][0] == y) || (tmp[x][0] == y && tmp[y][0] == x))ans++;}}for(int i = 1;i <= n;++i) if(!tmp[i].size() && C[val[i]].size() > 1) ans++;cout<<ans;return 0;
}

转载于:https://www.cnblogs.com/wxyww/p/bzoj2215.html

bzoj2215 POI2011 Conspiracy相关推荐

  1. # bzoj2215: [Poi2011]Conspiracy 2-sat

    bzoj2215: [Poi2011]Conspiracy 2-sat 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2215 思路 一个点的 ...

  2. BZOJ2215[Poi2011]Conspiracy——2-SAT+tarjan缩点

    题目描述 Byteotia的领土被占领了,国王Byteasar正在打算组织秘密抵抗运动.国王需要选一些人来进行这场运动,而这些人被分为两部分:一部分成为同谋者活动在被占领区域,另一部分是后勤组织在未被 ...

  3. bzoj2215: [Poi2011]Conspiracy

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2215 思路:一道很好的2-sat题 首先一个人要么分配给同谋者,要么分配给后勤组织 这可以考 ...

  4. bzoj2215[POI2011]Conspiracy

    题意 给出n个点的一个图,要求把所有点分成两部分,一部分是一个团,一部分是一个独立集.n<=5000 分析 记录自己的愚蠢... 首先考虑如何判断存在可行方案,那么每个点要么属于团,要么属于独立 ...

  5. BZOJ2215 : [Poi2011]Conspiracy

    考虑构造一组可行解,把每个点拆成两个点x0,x1,x0表示后勤组织,x1表示同谋者. 若x与y认识,则x1向y0连边. 若x与y不认识,则x0向y1连边. 如此求出一组2-SAT的可行解,如果无解则答 ...

  6. 「POI2011 R1」Conspiracy

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

  7. [bzoj2527][Poi2011]Meteors_整体二分_树状数组

    Meteors bzoj-2527 Poi-2011 题目大意:题目链接. 注释:略. 想法: 首先答案可以离线,且具有单调性. 这里的单调性就是随着时间的推移,每个国家收集的陨石数增加. 不难想到整 ...

  8. [bzoj2213][Poi2011]Difference_动态规划

    Difference bzoj-2213 Poi-2011 题目大意:已知一个长度为n的由小写字母组成的字符串,求其中连续的一段,满足该段中出现最多的字母出现的个数减去该段中出现最少的字母出现的个数最 ...

  9. 洛谷 P3521 [POI2011]ROT-Tree Rotations 解题报告

    P3521 [POI2011]ROT-Tree Rotations 题意:递归给出给一棵\(n(1≤n≤200000)\)个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 大体 ...

最新文章

  1. 基于深度学习的目标检测算法:SSD——常见的目标检测算法
  2. Mac OS X:在标题栏上显示目录完整路径
  3. JavaScript 是如何工作的:解析、抽象语法树(AST)+ 提升编译速度5个技巧
  4. python循环顶帖_设计Python数据库连接池1-对象的循环引用问题
  5. 解决老是提示找不到Mapper文件无法执行定义的方法问题!
  6. 小鹏的全语音车载系统什么名堂?
  7. 海报展示样机模板|给你一个现实的环境
  8. 【报告分享】2022中国品牌出海模式洞察及趋势情况报告.pdf(附下载链接)
  9. matlab电机系统建模与仿真软件下载,同步电机模型的MATLAB仿真的设计(最终版)...
  10. 飞思卡尔16位单片机(一)——飞思卡尔单片机简介
  11. Kettle数据抽取实战之四:网页数据抽取
  12. echarts树图tree制作家谱教程
  13. 脱壳总结之 - upx,aspack, FSG,PECompact2.X,WinUpack脱壳
  14. protobuf 中 repeated fields 细节
  15. 13位时间戳单位为毫秒,10位字符串单位为秒。时间戳转换日期数字格式100%全乎
  16. 除adsense外适合英文站的国外广告联盟(4/12/2011更新)
  17. 简单模拟医院叫号系统
  18. Vue v-modle理解
  19. 大神的傅里叶变换,一定要看看
  20. icpc西部区域赛_江西软件大学夺得第八届高校联赛西部大区总冠军

热门文章

  1. Count bits set in parallel(查找32位整形数中置1的个数)
  2. java netty wss_netty实现websocket客户端(支持wss安全连接)
  3. RPA - Robotic process automation (机器人流程自动化)
  4. 贝壳找房内部职级_贝壳找房组织架构再调整:战区扩至七个 任命四名区首
  5. 数据分析入门:初识数据埋点(一)
  6. 西班牙语学习、关系代词que的用法
  7. 微信Mac版 v3.0.0正式版上线!mac电脑上也能在朋友圈点赞和互动!
  8. 微信小程序计算两个日期之间相差几天
  9. InvalidArgumentError: You must feed a value for placeholder tensor ‘conv2d_12_input‘ with dtype floa
  10. 8 9区别 endnote7_带鱼5-7和8-9的区别