bzoj2215: [Poi2011]Conspiracy 2-sat

链接

https://www.lydsy.com/JudgeOnline/problem.php?id=2215

思路

一个点的属性为去当同谋者和后勤两种
求出一种方案来很简单(只需要用简单的2-sat)
我们发现一条特别重要的性质:
一个方案只会由已经求出的其他任意一种方案改变一方的一个人得来
(基本看出来就稳了)
因为两个人不能同时过去(显然)
那么我们先求出一种方案
然后统计ok[i],表示i到对面冲突的点的个数
显然只有几种情况(大力分情况讨论)
①.一个间谍去后勤
②.一个后勤区去间谍
就是ok==0的个数(注意双方都不能为0个人)
③.间谍和后勤互换(容易发现交换的两个人一定一个是0,一个是1)
好了。

错误

tarjan求方案的方向居然写反了、、、
还有mp的i+n没减n

代码

#include <iostream>
#include <cstdio>
#include <vector>
#define iter vector<int>::iterator
const int N=5007;
using namespace std;
int read() {int x=0,f=1;char s=getchar();for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';return x*f;
}
int n,ok[N<<1],dsr;
bool mp[N][N];
vector<int> ans[2];
struct node {int v,nxt;
}e[N*N];
int head[N<<1],tot;
void add(int u,int v) {e[++tot].v=v;e[tot].nxt=head[u];head[u]=tot;
}
int dfn[N<<1],low[N<<1],stak[N<<1],top,cnt,belong[N<<1],vis[N<<1];
void tarjan(int u) {dfn[u]=low[u]=++cnt;vis[u]=1;stak[++top]=u;for(int i=head[u];i;i=e[i].nxt) {int v=e[i].v;if(!dfn[v]) {tarjan(v);low[u]=min(low[u],low[v]);} else if(vis[v]) {low[u]=min(low[u],dfn[v]);}}if(low[u]==dfn[u]) {belong[0]++;while(stak[top]!=u) {vis[stak[top]]=0;belong[stak[top]]=belong[0];top--;} top--;vis[u]=0;belong[u]=belong[0];}
}
int main() {n=read();for(int i=1;i<=n;++i) {int k=read();for(int j=1;j<=k;++j) mp[i][read()]=1;}for(int i=1;i<=n;++i) {for(int j=1;j<i;++j) {if(mp[i][j]) {add(i,j+n),add(j,i+n);} else {add(i+n,j),add(j+n,i);}}}for(int i=1;i<=n+n;++i)if(!dfn[i])tarjan(i);for(int i=1;i<=n;++i) {if(belong[i]==belong[i+n]) {puts("0");return 0;}}for(int i=1;i<=n;++i) {if(belong[i] < belong[i+n]) ans[0].push_back(i);else ans[1].push_back(i+n);}if(ans[0].size()&&ans[1].size()) dsr++;for(iter i=ans[0].begin();i!=ans[0].end();++i) {for(iter j=ans[1].begin();j!=ans[1].end();++j) {if(!mp[*i][*j-n]) ok[*i]++;     }}for(iter i=ans[1].begin();i!=ans[1].end();++i) {for(iter j=ans[0].begin();j!=ans[0].end();++j) {if(mp[*i-n][*j]) ok[*i]++;}}int siz_0[2]={};for(int k=0;k<=1;++k)for(iter i=ans[k].begin();i!=ans[k].end();++i)if(!ok[*i]) siz_0[k]++;if(ans[0].size()>1) dsr+=siz_0[0];if(ans[1].size()>1) dsr+=siz_0[1];for(iter i=ans[0].begin();i!=ans[0].end();++i) {if(ok[*i]==1) {for(iter j=ans[1].begin();j!=ans[1].end();++j) {if(!mp[*i][*j-n]&&!ok[*j]) dsr++;}}}for(iter i=ans[1].begin();i!=ans[1].end();++i) {if(ok[*i]==1) {for(iter j=ans[0].begin();j!=ans[0].end();++j) {if(mp[*i-n][*j]&&!ok[*j]) dsr++;}}}printf("%d\n",dsr);return 0;
}

转载于:https://www.cnblogs.com/dsrdsr/p/10490147.html

# bzoj2215: [Poi2011]Conspiracy 2-sat相关推荐

  1. bzoj2215 POI2011 Conspiracy

    题意 给出一张图,将其分为一个团和一个独立集.问有多少种方案.团和独立集都不能为空 思路 先考虑找可行方案应该怎么做 显然是个\(2-sat\).可以将分到团和独立集中分别看为0和1. 如果两个点之间 ...

  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. 模板 - 2 - SAT问题

    整理的算法模板合集: ACM模板 注意一个坑,2SAT问题中如果要求你输出方案,如果你的代码输出的跟样例不一样,不要着急,因为2SAT 问题本来就是有多解,结果我样例不过,交上去就A了 方案输出时,c ...

  8. 计算机学院 图论方向,成电计算机学院本科生在计算机科学理论方向重要国际会议SAT上发表论文...

    近日,计算机科学与工程学院(网络空间安全学院)2017级本科生和肖鸣宇教授撰写的论文"A Fast Algorithm for SAT in Terms of Formula Length& ...

  9. MIT录取不再看SAT科目成绩:曾是华裔传统优势,数学等学科测验更是中国留学生强项...

    晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 美国麻省理工学院今天在招生网站上宣布,决定不再考虑将SAT科目考试作为录取过程的一部分. 这一决定从2020~2021学年开始生效. SA ...

最新文章

  1. Oracle10g客户端远程连接数据库全过程[转]
  2. 微信8.0内测更新!!!(附内测体验资格)
  3. 超详细的Python matplotlib 绘制直方图 赶紧收藏
  4. 安装完Hadoop之后,命令行输入hadoop或hdfs却找不到命令的解决方法
  5. 流畅的python读书笔记-第一章Python 数据模型
  6. linux 新开窗口到最前,怎么设置一个窗口总是在电脑桌面的最前
  7. Qt访问SQLite数据库
  8. 采购订单检查/保存BADI使用
  9. JPA时间注解(转)
  10. 跨域405(Method Not Allowed)问题
  11. java中find方法_Java Document.find方法代码示例
  12. php调用谷歌翻译接口_一个google翻译的php调用方式
  13. python jieba词频统计英文文本_python实战,中文自然语言处理,应用jieba库来统计文本词频...
  14. Lucene搜索引擎
  15. Java中J.U.C扩展组件之ForkJoinTask和ForkJoinPool
  16. matlab2c使用c++实现matlab函数系列教程-intersect函数
  17. Hive安装详细步骤
  18. WIN7操作系统IE11的离线安装(有时间总结下)
  19. [人工智能-深度学习-38]:卷积神经网络CNN - 常见分类网络- ResNet网络架构分析与详解
  20. 节奏大师小游戏制作流程

热门文章

  1. Programming Exercise 6:Support Vector Machines
  2. linux系统中软盘的名称,linux中软盘的使用
  3. 人工智能时代,最容易被人工智能取代的职位是什么
  4. python爬取百度云资源分享吧_python爬取百度云盘资源
  5. 【数据治理】电力行业数据治理解决方案
  6. 【739】单调栈应用
  7. 网易视频云:HBase BlockCache系列-性能对比测试报告
  8. Oracle数据库,建库建表
  9. java 创建word文件_Java 创建Word
  10. flutter Container 的decoration 属性