题目描述

Byteotia的领土被占领了,国王Byteasar正在打算组织秘密抵抗运动。国王需要选一些人来进行这场运动,而这些人被分为两部分:一部分成为同谋者活动在被占领区域,另一部分是后勤组织在未被占领的领土上运转。但是这里出现了一个问题: 1. 后勤组织里的任意两人都必须是熟人,以促进合作和提高工作效率。 2. 同谋者的团体中任意两人都不能是熟人。 3. 每一部分都至少要有一个人。国王想知道有多少种分配方案满足以上条件,当然也有可能不存在合理方案。现在国王将这个问题交由你来解决!

输入

第一行一个整数n(2<=n<=5000)表示有n个人参与该抵抗运动,标号为1..n。 之后有n行,第i行的第一个数ki(0<=ki<=n-1)表示i认识ki个人,随后的ki个数表示i的熟人。 p.s.输入满足:如果i是x的熟人,x会在i的序列中出现同时i也会出现在x的熟人序列中。

输出

符合条件的方案总数。

样例输入

4
2 2 3
2 1 3
3 1 2 4
1 3

样例输出

3

提示

Hint 1和4分到同谋者组织,2和3为后勤组织。 2和4分到同谋者组织,1和3为后勤组织。 4单独分到同谋者组织,1和2、3为后勤组织。

为了方便假设后勤组织为A,同谋组织为B

用邻接矩阵存每个人之间的认识情况,如果两个人认识就不能都在B,如果两个人不认识就不能都在A,枚举每个人之间的认识情况来2-SAT连边。

因为对于任意两个人在两种不同的方案中,他们不能一种方案都在A,另一种方案都在B。

所以在找到任意一组不冲突方案后,只能通过只将A中一个人移到B中或只将B中一个人移到A中或只将A和B中的各一个人调换来得到其他方案。

对于每个人,我们预处理出另一个集合中与他冲突的人数,什么是冲突的人?假设x,y认识,x在A中,y在B中,那么y就是x的冲突的人,因为如果x移到B中与y冲突。

先来考虑交换两个人的方案数。

如果一个人x的冲突人数>=2显然他不能动。

如果一个人x的冲突人数=1且与他冲突的人y没有冲突人数或与他冲突的人y只有一个冲突人数且这个冲突的人就是x,那么他们两个可以交换。

假设A中没有冲突人数的人有a个,B中有b个,那么这些人随便交换,方案数是a*b。

再来考虑移动一个人的方案数。

如果一个人没有冲突人数且他当前所在集合不只有他一个人,那么他能移到对面集合。

最后还要判断最开始随便找的一个不冲突方案是否每个集合都有人。

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int k,x;
int m[5010][5010];
int vis[10010];
int dep[10010];
int low[10010];
int s[10010];
vector<int>q[10010];
int head[10010];
int to[25000010];
int next[25000010];
int top;
int t[10010];
int v[10010];
int num;
int cnt;
int tot;
int now;
int ans;
int A[5010];
int B[5010];
int a,b;
int miku[10010];
int NIE[10010];
void add(int x,int y)
{tot++;next[tot]=head[x];head[x]=tot;to[tot]=y;
}
void tarjan(int x)
{t[++top]=x;low[x]=dep[x]=++num;vis[x]=1;for(int i=head[x];i;i=next[i]){if(!dep[to[i]]){tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}else if(vis[to[i]]){low[x]=min(low[x],dep[to[i]]);}}if(dep[x]==low[x]){cnt++;do{now=t[top];top--;s[now]=cnt;vis[now]=0;}while(now!=x);}
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&k);for(int j=1;j<=k;j++){scanf("%d",&x);m[i][x]=1;}}for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){if(m[i][j]){add(i+n,j);add(j+n,i);}else{add(i,j+n);add(j,i+n);}}}for(int i=1;i<=2*n;i++){if(!dep[i]){tarjan(i);}}for(int i=1;i<=n;i++){if(s[i]==s[i+n]){printf("0");return 0;}if(s[i]<s[i+n]){A[++a]=i;}else{B[++b]=i;}}if(a&&b){ans++;}for(int i=1;i<=a;i++){for(int j=1;j<=b;j++){if(m[A[i]][B[j]]){NIE[A[i]]++;miku[A[i]]=B[j];}}}for(int i=1;i<=b;i++){for(int j=1;j<=a;j++){if(!m[B[i]][A[j]]){NIE[B[i]]++;miku[B[i]]=A[j];}}}for(int i=1;i<=n;i++){if(NIE[i]==1){if(NIE[miku[i]]==1&&miku[i]>i&&miku[miku[i]]==i){ans++;}else if(!NIE[miku[i]]){ans++;}}}int t1=0;int t2=0;for(int i=1;i<=n;i++){if(!NIE[i]){if(s[i]<s[i+n]&&a>1){ans++;}if(s[i]>s[i+n]&&b>1){ans++;}if(s[i]<s[i+n]){t1++;}else{t2++;}}}ans+=t1*t2;printf("%d",ans);
}

转载于:https://www.cnblogs.com/Khada-Jhin/p/9719608.html

BZOJ2215[Poi2011]Conspiracy——2-SAT+tarjan缩点相关推荐

  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\).可以将分到团和独立集中分别看为0和1. 如果两个点之间 ...

  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. BZOJ 1051 受欢迎的牛(Tarjan缩点)

    1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4573  Solved: 2428 [Submit][S ...

  7. 【图论】Tarjan 缩点

    [Tarjan]缩点 在一个点N数据极大的图中,直接SPFA或者记忆花搜索时间超限,那么我们可以利用Tarjan缩点来减少N. 举个例子: 如上图:3,6两点为该图中的强连通分量,我们可以将它们看做一 ...

  8. bzoj1051 [HAOI2006]受欢迎的牛 tarjan缩点

    题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢"是可以传递的--如果A喜 欢B,B喜 ...

  9. 洛谷P4742(tarjan缩点+拓扑DP)

    https://www.luogu.org/problemnew/show/P4742 题目背景 [Night - 20:02[Night−20:02 P.M.]P.M.] 夜空真美啊--但是--快要 ...

最新文章

  1. Java——this
  2. QML实现酷炫的 Cover Flow 效果(PathView)
  3. 设计和实时视图不一样_三室两厅家装设计,如何打造出不一样的感觉?
  4. String、StringBuuffer、StringBuilder三者的区别
  5. Java字符流的使用
  6. client中周期性边界_FLUENT创建周期性边界条件方法
  7. SQL语句中exists/not exists的用法分析
  8. PowerDesigner16.5下载
  9. 首度亮相服贸会,亚马逊云科技如何演绎“大象起舞”?
  10. 冰点文库的替代品【Wenku Doc Downloader】用于下载各种文库的材料
  11. 经典JavaScript正则表达式实战(转)
  12. STM32f407程序移植到GD32F407
  13. 小麦苗博客用到的图片
  14. java中outer的用法
  15. 【Docker】linux下docker的卸载
  16. 【正点原子I.MX6U-MINI】修改开机内核Logo和进度条界面Logo(一)
  17. LoRaWAN介绍13 SX1301
  18. 国科大 - 高级人工智能(沈华伟等)- 期末复习 - 试卷
  19. 6、python-mongodb获取数据存储到sql server
  20. 计算机开多位数立方根原理,开立方

热门文章

  1. python笔记2(函数 面向对象 文件编程 上下文管理器)
  2. 行业操作系统行业深度报告 华为鸿蒙系统,操作系统行业深度报告:华为鸿蒙系统、安卓和未来.docx...
  3. tf.ones_like(tensor, dtype=None, name=None, optimize=True)示例
  4. 利用OpenCv读取一张图片并显示
  5. Navicat 2003-can't connect to MYSQL server on 'localhost'(10061)
  6. HikariPool使用MySQL/MariaDB数据库报错解决:java.sql.SQLException: Access denied for user 'root'@'localhost' (u
  7. ubuntu/debian 安装SSH,并开启
  8. C++_STL——stack
  9. K8S 最佳实践-映射外部服务 Endpoints / ExternalName
  10. 【Netty】传输(Transport)