[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个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺 ...
随机推荐
- Golang聊天室
一.前期准备 前期准备 需要 import "net"包 IP 类型,其中一个重要的方法是 IP.ParseIP(ipaddr string)来判断是否是合法的 IP 地址 TCP ...
- Java如何操作对象(bean)进行动态排序?
原文出自:https://blog.csdn.net/seesun2012 简介如题:Java如何操作对象(bean)进行动态排序?Java实体类(bean)动态排序? 原理:利用反射根据指定的属性值 ...
- 屏蔽F1~F12的快捷键的js函数
function window.onhelp(){return false} //屏蔽F1帮助 /*keyCod从113-123分别禁用了F2-F12键,13禁用了回车键(Enter),8禁用了退格键 ...
- JavaScript三大对象详细解说
Js三大对象 一 浏览器对象 浏览器窗口.文档document.URL地址等 常用的浏览器对象: 浏览器对象的分层结构 Window对象 (1) 属性 名称 说明 document 表示给定浏览器窗口 ...
- JS实现二叉树的创建和遍历
1.先说二叉树的遍历,遍历方式: 前序遍历:先遍历根结点,然后左子树,再右子树 中序遍历:先遍历左子树,然后根结点,再右子树 后续遍历:先遍历左子树,然后右子树,再根结点 上代码:主要还是利用递归 ...
- ASP.NET页面支持的指令
页面的处理指令 页面指令的处理用于配置执行该页面的运行时环境.在ASP.NET中,指令可以位于页面的任何位置,但良好且常见的习惯是将其置于文件的开始部分.除此,页面指令的名称是不区分大小写的,且指令的 ...
- [javaSE] IO流(递归查找指定文件)
递归方法,实现查找目录中以.java为后缀的文件路径,并存入文本文件中 定义一个静态方法fileToLine(),传入参数:File对象目录,List集合对象(List<File> 这样做 ...
- 13、IO (File、递归)
File File类的概述和作用 * A:File类的概述和作用 * a: File的概念 * File类是文件和目录路径名的抽象表示形式 * Java中把文件或者目录(文件夹)都封装成File对象 ...
- eclipse的debug技巧之一
如下图,断点设置的地方会在i==0时就停住,假如我们想在i等于某个值的时候才停住,那么可以添加“过滤条件” 具体操作是在debug模式下,右键breakpoints标签下我们所设置的断点,点击右键菜单 ...
- Windows命令行方式执行OracleSQL脚本
调用格式 sqlplus user/pwd@orcl @F:\DB_BAKFile\createpro.sql>>F:\DB_BAKFile\log\createpro.log SQL脚本 ...