[BZOJ 1124][POI 2008] 枪战 Maf
1124: [POI2008]枪战Maf
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 659 Solved: 259
[Submit][Status][Discuss]Description
有n个人,每个人手里有一把手枪。一开始所有人都选定一个人瞄准(有可能瞄准自己)。然后他们按某个顺序开枪,且任意时刻只有一个人开枪。因此,对于不同的开枪顺序,最后死的人也不同。
Input
输入n人数<1000000 每个人的aim
Output
你要求最后死亡数目的最小和最大可能
Sample Input
8
2 3 2 2 6 7 8 5Sample Output
3 5
不看数据范围可能看起来像是缩点树归的样子, 但是平常的 $O(n^2)$ 树归在这里显然需要 $\text{真-}Owys$ 才能过( $\text{-}Owys$大法好, $n^2$ 过 $5 \times 10^5$ )(雾
然后按照图论题的一般套路就该找规律了w(找不到规律就成了神tm不可做题了)
经过一波 $Tarjan$ 缩点后再YY我们可以得到以下结论:
首先对于最大死亡数来说:
当 $SCC$ 为一个点的最大死亡数在存在入边时为$1$, 否则为 $0$.
当 $SCC$ 为一个环的最大死亡数在存在入边时为 $SCC$ 中的结点数 $size$ , 否则为 $size-1$ (有一个点是无法杀死的)
当环存在入边时还要加上连入的环的结点数再减去其中的零入度结点(因为零入度结点不可能死亡).
然后是最小死亡数:
首先零入度结点必定无法杀死, 而零入度结点的目标必死. 所以我们可以在预处理时将零入度结点压入一个队列, 然后删除它和它的目标, 更新答案, 并将删掉的结点的目标的入度减去 $1$ . 因为杀死必死的人后可能它的目标的入度变成 $0$ 然后变成新的存活结点. 新的存活结点入队. 如此处理直至队列为空.
然后我们可以发现所有的链都会在这个过程中被处理掉, 也就是说图里应该删得只剩下几坨环了. 然后这时我们可以发现对于环来说, 若环中结点数为 $s$ , 则至少要死去 $\left \lceil \frac {s}{2} \right \rceil$ 个结点. (每次刚好隔开杀手, 隔一个死一个w)
如此处理即可求出最终解.
辣鸡分类讨论吃枣药丸(╯‵□′)╯︵┻━┻(雾
参考代码
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> const int MAXN=; int n;
int scc;
int Time;
int maxA;
int minA;
int dfn[MAXN];
int low[MAXN];
int size[MAXN];
int belong[MAXN];
int target[MAXN];
int inDegree[MAXN];
int inDegreeSCC[MAXN]; bool visited[MAXN]; std::stack<int> s; void Initialize();
void DFS(int); int main(){
std::queue<int> live;
Initialize();
for(int i=;i<=n;i++){
if(inDegree[i]==)
live.push(i);
}
while(!live.empty()){
int top=live.front();
live.pop();
visited[top]=true;
if(visited[target[top]])
continue;
minA++;
visited[target[top]]=true;
if((--inDegree[target[target[top]]])==&&!visited[target[target[top]]])
live.push(target[target[top]]);
}
for(int i=;i<=n;i++){
int cnt=;
if(!visited[i]){
int x=i;
do{
visited[x]=true;
cnt++;
x=target[x];
}while(x!=i);
}
if(cnt>)
minA+=(cnt+)/;
}
memset(visited,,sizeof(visited));
for(int i=;i<=n;i++){
if(dfn[i]==)
DFS(i);
}
for(int i=;i<=n;i++){
if(target[i]==i||belong[i]!=belong[target[i]])
inDegreeSCC[belong[target[i]]]++;
}
for(int i=;i<=scc;i++){
if(inDegreeSCC[i]>)
maxA+=size[i];
else
maxA+=size[i]-;
}
printf("%d %d\n",minA,maxA);
return ;
} void DFS(int root){
dfn[root]=low[root]=++Time;
visited[root]=true;
s.push(root);
if(visited[target[root]]){
low[root]=std::min(low[root],dfn[target[root]]);
}
else if(dfn[target[root]]==){
DFS(target[root]);
low[root]=std::min(low[root],low[target[root]]);
}
if(low[root]==dfn[root]){
scc++;
int top;
do{
top=s.top();
belong[top]=scc;
size[scc]++;
visited[top]=false;
s.pop();
}while(top!=root);
}
} inline void Initialize(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",target+i);
inDegree[target[i]]++;
}
}
Backup

[BZOJ 1124][POI 2008] 枪战 Maf的更多相关文章
- 【BZOJ 1124】[POI2008] 枪战Maf Tarjan+树dp
#define int long long using namespace std; signed main(){ 这个题一看就是图论题,然后我们观察他的性质,因为一个图论题如果没有什么性质,就是真· ...
- bzoj 1112 poi 2008 砖块
这滞胀题调了两天了... 好愚蠢的错误啊... 其实这道题思维比较简单,就是利用treap进行维护(有人说线段树好写,表示treap真心很模板) 就是枚举所有长度为k的区间,查出中位数,计算代价即可. ...
- BZOJ 1124: [POI2008]枪战Maf
1124: [POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 617 Solved: 236[Submit][Status ...
- bzoj 1124 [POI2008]枪战Maf 贪心
[POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 741 Solved: 295[Submit][Status][Disc ...
- [POI2008]枪战Maf
[POI2008]枪战Maf 题目 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的 ...
- [BZOJ 1013][JSOI 2008] 球形空间产生器sphere 题解(高斯消元)
[BZOJ 1013][JSOI 2008] 球形空间产生器sphere Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面 ...
- [POI 2008&洛谷P3467]PLA-Postering 题解(单调栈)
[POI 2008&洛谷P3467]PLA-Postering Description Byteburg市东边的建筑都是以旧结构形式建造的:建筑互相紧挨着,之间没有空间.它们共同形成了一条长长 ...
- 【BZOJ1124】[POI2008]枪战Maf 贪心+思路题
[BZOJ1124][POI2008]枪战Maf Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开 ...
- [POI2008]枪战Maf题解
问题 C: [POI2008]枪战Maf 时间限制: 1 Sec 内存限制: 256 MB 题目描述 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺 ...
随机推荐
- spring mongo data api learn
1 索引 1.1 单列索引 @Indexed @Field(value = "delete_flag") private Boolean deleteFlag = false; @ ...
- vue 实战问题-watch 数组或者对象
1.普通的watch data() { return { frontPoints: 0 } }, watch: { frontPoints(newValue, oldValue) { console. ...
- MySQL---5、可视化工具Navicat for MySQL安装配置
一.安装文件包下载 Navicat for MySQL 安装软件和破解补丁: 链接:https://pan.baidu.com/s/1oKcErok_Ijm0CY9UjNMrnA 密码:4xb1 ...
- 深入理解Java线程池:ScheduledThreadPoolExecutor
介绍 自JDK1.5开始,JDK提供了ScheduledThreadPoolExecutor类来支持周期性任务的调度.在这之前的实现需要依靠Timer和TimerTask或者其它第三方工具来完成.但T ...
- redisTemplate 总结
依赖jar包 jackson <dependency> <groupId>com.fasterxml.jackson.core</groupId> <arti ...
- Spring FactoryBean用法
最近在看spring ioc源码,看到FactoryBean这个内容.这个和BeanFactory的区别 1. BeanFactory: 生成bean的工厂,是一个接口,定义了很多方法 2. Fact ...
- SqlServer之一些小问题
如何用变量代替字段名? 将语句赋给一个varchar 变量,下列语句等价于(假设传进去的@id=’name‘):'select name from 表名' 如果直接执行这个语句,是没用的.@id不会 ...
- sublime Text3汉化和激活注册码
sublimeText3 很不错,前面几天下了vscore学习Node.js,感觉有点懵,今天下载sublimeText3,遇到的一些小问题,在这里说说: 百度云:https://pan.baidu. ...
- 关于MyEclipse2017Ci10版本的破解和Tomcat9.0的安装搭配使用
昨天和今天就忙这两件事情了.废话不多说直接上干货! 首先是关于Myeclipse2017的破解,关于这个破解,网上的资源和文件很多,可以自行下载,我就不贴链接了. 我要说的是破解的问题,在这里我们要注 ...
- JavaScript的进阶之路(四)理解对象1
对象是JavaScript的基本数据类型.简单的名值对组成了对象,BUT:还可以从一个被称为原型的对象继承属性,对象的方法通常就是继承的属性. 对象最常见的用法有:创建.设置.查找.删除.检测.枚举它 ...