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;
}

# bzoj2215: [Poi2011]Conspiracy 2-sat的更多相关文章

  1. bzoj2215: [Poi2011]Conspiracy

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

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

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

  3. POI2011题解

    POI2011题解 2214先咕一会... [BZOJ2212][POI2011]Tree Rotations 线段树合并模板题. #include<cstdio> #include< ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. POI做题笔记

    POI2011 Conspiracy (2-SAT) Description \(n\leq 5000\) Solution 发现可拆点然后使用2-SAT做,由于特殊的关系,可以证明每次只能交换两个集 ...

  6. 「POI2011 R1」Conspiracy

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

  7. BZOJ2527: [Poi2011]Meteors

    补一发题解.. 整体二分这个东西,一开始感觉复杂度不是很靠谱的样子 问了po姐姐,说套主定理硬干.. #include<bits/stdc++.h> #define ll long lon ...

  8. 多边形碰撞 -- SAT方法

    检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...

  9. BZOJ2276: [Poi2011]Temperature

    2276: [Poi2011]Temperature Time Limit: 20 Sec  Memory Limit: 32 MBSubmit: 293  Solved: 117[Submit][S ...

随机推荐

  1. Self hosted OWIN 绑定地址127.0.0.1,外网无法访问

    static void Main()         {             string baseAddress = "http://localhost:4004/";   ...

  2. Windows server 2008 R2实现多用户远程连接 (转)

    经常使用远程桌面的朋友可能会注意到,Windows server 2008 R2中,远程桌面最多只允许两个人远程连接,第三个人就无法连接过去,但是生产环境中有一些服务器可能有许多人需要连接上去,而微软 ...

  3. STL之Map和multimap容器

    1.Map和multimap容器 1)map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. 2)map中key值是唯一的.集合中的元素按一 ...

  4. jQuery工具--$.each()和$.merge()

       jQuery.each(object, [callback])或者jQuery(object).each([callback]) 概述 通用遍历方法,可用于遍历对象和数组. 不同于遍历 jQue ...

  5. Error resolving version for plugin 'org.codehaus.mojo:tomcat-maven-plugin'

    从 SNV 导入新工程后,启动工程,但 Maven 报错: Error resolving version for plugin 'org.codehaus.mojo:tomcat-maven-plu ...

  6. mybatis源码解析8---执行mapper接口方法到执行mapper.xml的sql的过程

    上一篇文章分析到mapper.xml中的sql标签对应的MappedStatement是如何初始化的,而之前也分析了Mapper接口是如何被加载的,那么问题来了,这两个是分别加载的到Configura ...

  7. 高性能NIO框架Netty-对象传输

    http://cxytiandi.com/blog/detail/17403 上篇文章高性能NIO框架Netty入门篇我们对Netty做了一个简单的介绍,并且写了一个入门的Demo,客户端往服务端发送 ...

  8. Codeforces 237A - Free Cash

    题目链接:http://codeforces.com/problemset/problem/237/A Valera runs a 24/7 fast food cafe. He magically ...

  9. Python基础二_操作字符串常用方法、字典、文件读取

    一.字符串常用方法: name.captitalize()                       #字符串首字母大写 name.center(50,'*')                   ...

  10. vue -resource 文件提交提示process,或者拦截处理

    this.$http.post('url',fd||data,{emulateJSON:true}).then(fn(res){},fn(res){}) process成功案例 _self.$http ...