洛谷P3513 [POI2011]KON-Conspiracy
洛谷P3513 [POI2011]KON-Conspiracy
题目描述
Byteotia的领土被占领了,国王Byteasar正在打算组织秘密抵抗运动。
国王需要选一些人来进行这场运动,而这些人被分为两部分:一部分成为同谋者活动在被占领区域,另一部分是后勤组织在未被占领的领土上运转。
但是这里出现了一个问题:
1、后勤组织里的任意两人都必须是熟人,以促进合作和提高工作效率。
2、同谋者的团体中任意两人都不能是熟人。
3、每一部分都至少要有一个人。国王想知道有多少种分配方案满足以上条件,当然也有可能不存在合理方案。
现在国王将这个问题交由你来解决!
分析
如果没有输出方案数,那么这一道题就是一个裸的\(2-SAT\)问题
我们将一个点拆成两个点
其中编号为\(1-n\)的代表后勤,编号为\(n+1-2n\)的代表同谋
如果\(i\)和\(j\)是熟人,那么我们从\(i+n\)到\(j\)建一条边
如果\(i\)和\(j\)不是熟人,那么我们从\(i\)到\(j+n\)建一条边
我们按照正常的流程跑一个\(Tarjan\)就可以了
方案数为\(0\)的情况比较好求,即出现\(shuyu[i]=shuyu[i+n]\)的情况
对于有解的情况,我们要分类讨论
首先我们将所有的点分成两个集合,一个集合为后勤,另一个集合为同谋
对于后勤中的某个点,如果他和同谋中的某个点是熟人,那么我们就不能将该点加入同谋的集合
同样地,对于同谋中的某个点,如果他和后勤中的某个点不是熟人,那么我们就不能将该点加入后勤的集合
我们将这样的点称为冲突点
我们对于每一个点,都找出它的所有冲突点
一个显然的结论是,我们不能从一个集合移动两个点到达另一个集合
这样必定会产生冲突
因为如果我们将后勤集合中的两个点扔到同谋集合,那么同谋集合会出现熟人,反之亦然
因此,我们每次最多只能改变一个点的位置
因此,对于冲突点的数量大于\(2\)的节点,我们不去考虑它
如果某一个节点的冲突点的数量为\(1\),那么我们可以把该节点的冲突点拿到当前节所在的集合
前提是该节点的冲突点的冲突点的数量为\(0\)
如果节点的冲突点的数量为\(0\),那么我们可以将其扔到另一个集合中
同时,如果处在不同集合的两个点的冲突数量都为\(0\),我们可以将这两个点交换,我们用乘法原理解决即可
代码
#define fastcall __attribute__((optimize("-O3")))
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=5e3+5;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
struct asd{
int to,next;
}b[maxn*maxn];
int head[maxn],tot=1;
void ad(int aa,int bb){
b[tot].to=bb;
b[tot].next=head[aa];
head[aa]=tot++;
}
int dfn[maxn],low[maxn],dfnc,sta[maxn],top,shuyu[maxn],js;
bool vis[maxn][maxn];
void tar(int xx){
dfn[xx]=low[xx]=++dfnc;
sta[++top]=xx;
for(int i=head[xx];i!=-1;i=b[i].next){
int u=b[i].to;
if(!dfn[u]){
tar(u);
low[xx]=min(low[xx],low[u]);
} else if(!shuyu[u]){
low[xx]=min(low[xx],dfn[u]);
}
}
if(low[xx]==dfn[xx]){
js++;
while(1){
int y=sta[top--];
shuyu[y]=js;
if(y==xx) break;
}
}
}
int hq[maxn],tm[maxn],jlhq,jltm,ctd[maxn],mat[maxn];
bool istm[maxn];
int main(){
memset(head,-1,sizeof(head));
int n;
n=read();
for(int i=1;i<=n;i++){
int t;
t=read();
for(int j=1;j<=t;j++){
int aa;
aa=read();
vis[i][aa]=1;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) continue;
if(vis[i][j]) ad(i+n,j);
else ad(i,j+n);
}
}
for(int i=1;i<=n*2;i++){
if(!dfn[i]) tar(i);
}
for(int i=1;i<=n;i++){
if(shuyu[i]==shuyu[i+n]){
printf("0\n");
exit(0);
} else if(shuyu[i]<shuyu[n+i]){
hq[++jlhq]=i;
} else {
tm[++jltm]=i;
istm[i]=1;
}
}
int ans=(jlhq&&jltm),tmp1=0,tmp2=0;
for(int i=1;i<=jlhq;i++){
for(int j=1;j<=jltm;j++){
if(vis[hq[i]][tm[j]]){
++ctd[hq[i]];
mat[hq[i]]=tm[j];
}
}
}
for(int i=1;i<=jltm;i++){
for(int j=1;j<=jlhq;j++){
if(!vis[tm[i]][hq[j]]){
++ctd[tm[i]];
mat[tm[i]]=hq[j];
}
}
}
for(int i=1;i<=n;i++){
if(ctd[i]==1){
if(ctd[mat[i]]==0) ans++;
}
}
for(int i=1;i<=n;i++){
if(ctd[i]==0){
if((istm[i] && jltm>1) || (!istm[i] && jlhq>1)) ans++;
if(istm[i]) tmp1++;
else tmp2++;
}
}
printf("%d\n",ans+tmp1*tmp2);
return 0;
}
洛谷P3513 [POI2011]KON-Conspiracy的更多相关文章
- [洛谷P3527] [POI2011]MET-Meteors
洛谷题目链接:[POI2011]MET-Meteors 题意翻译 Byteotian Interstellar Union有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1 ...
- BZOJ2212或洛谷3521 [POI2011]ROT-Tree Rotations
BZOJ原题链接 洛谷原题链接 线段树合并裸题. 因为交换子树只会对子树内部的逆序对产生影响,所以我们计算交换前的逆序对个数和交换后的个数,取\(\min\)即可. 对每个叶子节点建一棵动态开点线段树 ...
- 洛谷P3515 [POI2011]Lightning Conductor(动态规划,决策单调性,单调队列)
洛谷题目传送门 疯狂%%%几个月前就秒了此题的Tyher巨佬 借着这题总结一下决策单调性优化DP吧.蒟蒻觉得用数形结合的思想能够轻松地理解它. 首先,题目要我们求所有的\(p_i\),那么把式子变一下 ...
- 洛谷 P3527 [POI2011]MET-Meteors 解题报告
P3527 [POI2011]MET-Meteors 题意翻译 \(\tt{Byteotian \ Interstellar \ Union}\)有\(N\)个成员国.现在它发现了一颗新的星球,这颗星 ...
- 洛谷 P3521 [POI2011]ROT-Tree Rotations 解题报告
P3521 [POI2011]ROT-Tree Rotations 题意:递归给出给一棵\(n(1≤n≤200000)\)个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 大体 ...
- 洛谷P3521 [POI2011]ROT-Tree Rotation [线段树合并]
题目传送门 Tree Rotation 题目描述 Byteasar the gardener is growing a rare tree called Rotatus Informatikus. I ...
- 洛谷P3527 [POI2011]MET-Meteors [整体二分]
题目传送门 Meteors 格式难调,题面就不妨放了. 分析: 一道整体二分的练手题. 就是一般的整体二分的套路,但是要注意,将修改和询问加入队列的时候要先加修改再加询问.另外,博主代码打得太丑,常数 ...
- [洛谷P3521][POI2011]ROT-Tree Rotations
题目大意:给一棵$n(n\leqslant2\times10^5)$个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少.输出最少的逆序对个数 题解:线段树合并,对于每个节点求出交换 ...
- 洛谷P3515 [POI2011]Lightning Conductor(决策单调性)
题意 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt(abs(i-j)) ...
随机推荐
- AI芯片
课程作业,正好自己也在学深度学习,正好有所帮助,做了深度学习的AI芯片调研,时间比较短,写的比较仓促,大家随便看看 近年来,深度学习技术,如卷积神经网络(CNN).递归神经网络(RNN)等,成为计算机 ...
- mysql实现主从复制/主从同步
业务场景 小公司业务代码存于一个服务器上,而这个服务器有的时候回宕机,导致业务停顿,造成影响.这个时候 就需要做高可用 两个ngix+两个tomcat+两个mysql实现高可用,避免单点问题.中间使用 ...
- js 对象数组根据某个名称删除数组中的对象
delArrayItem: function (array,item) { const index = array.findIndex(text => text.name === item.na ...
- 手写SpringBoot自动配置及自定义注解搭配Aop,实现升级版@Value()功能
背景 项目中为了统一管理项目的配置,比如接口地址,操作类别等信息,需要一个统一的配置管理中心,类似nacos. 我根据项目的需求写了一套分布式配置中心,测试无误后,改为单体应用并耦合到项目中.项目中使 ...
- CF940E Cashback 线段树优化DP
题目描述 Since you are the best Wraith King, Nizhniy Magazin «Mir» at the centre of Vinnytsia is offerin ...
- Apache 阿帕奇 配置运行环境
阿帕奇 Apache 是一个很常用的服务器环境. 安装阿帕奇后,需要对配置文件进行修改,才能使用. https.conf是阿帕奇的配置文件,地址在 阿帕奇的安装目录\conf\httpd.conf 默 ...
- ant design pro/前端/JS:实现本地运行https
工具:github---mkcert 用于生成本地证书 ant p版本:1.0.0 这里我只说如何给antp部署https,以及会遇到的问题解决,其他请看原文参考 1.用mkcert生成证书,去git ...
- springMVC -- 对接UEditor(富文本编辑器)
工作中需要用到UEditor编辑文本,在与springMVC进行整合时,出现了一些问题,结果导致,在进行图片上传时出现如下提示: 上网查询了很多相关资料,此处简要记录下,防止以后遇到类似问题. 一种方 ...
- log4j日志打印级别动态调整
1,为什么日志打印级别要动态调整? 随着项目越来越大,访问量也越来越高,遇到问题时想要排查,可是日志一打开却刷的太快太快,不好排查问题,有的时候甚至因为短时间打印日志太多,严重影响了性能,这个时候日志 ...
- python迭代器和装饰器
一.迭代器 1.迭代器协议:对象必须提供一个__next__()方法,执行该方法要么返回迭代中的下一个对象,要么引起一个StopIteration异常以终止迭代,迭代只能向后进行不能往前回退 2.可迭 ...