[POI2008]枪战Maf

题目

有n个人,每个人手里有一把手枪。一开始所有人都选定一个人瞄准(有可能瞄准自己)。然后他们按某个顺序开枪,且任意时刻只有一个人开枪。因此,对于不同的开枪顺序,最后死的人也不同。

INPUT

输入n人数<1000000 每个人的aim

OUTPUT

你要求最后死亡数目的最小和最大可能

SAMPLE

INPUT

8

2 3 2 2 6 7 8 5

OUTPUT

3 5

解题报告

考试时候打出了tarjan,然而不会用= =

正解:

tarjan

我们分连通块来考虑

首先自杀的一定死

一个环上的,最多死 点数-1 个(一个人开始开枪,然后被杀,最后只剩一个),最少死一半(假如少于一半,那么必然有至少一条直接相连的边没有被砍,必然还会死人)

一个环加上内向树,最多死 点数-入度为0的个数

最少如何处理呢?

入度为0的死不了(没人打他)

将他们推入队列,他们的目标一定死,那就让他们死,然后他们的目标入度减1,看看是否变为入度为0,依次处理

最后剩下的一定是一堆环

然后就可以在欢声笑语中打出GG

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
inline int read(){
int sum();
char ch(getchar());
for(;ch<''||ch>'';ch=getchar());
for(;ch>=''&&ch<='';sum=sum*+(ch^),ch=getchar());
return sum;
}
int n;
struct edge{
int s,e,n;
}a[];
int pre[],tot;
inline void insert(int s,int e){
a[++tot].s=s;
a[tot].e=e;
a[tot].n=pre[s];
pre[s]=tot;
}
inline int my_max(int a,int b){
return a>b?a:b;
}
inline int my_min(int a,int b){
return a<b?a:b;
}
struct node{
int id;
}hh[];
bool die[];
int target[];
int ans_min(),ans_max();
int in[];
int low[],dfn[],zhan[],bl[],size[];
int cnt,top,qlt;
bool vis[];
int cl[];
inline void tarjan(int u){
dfn[u]=low[u]=++cnt;
zhan[++top]=u;
vis[u]=;
for(int i=pre[u];i!=-;i=a[i].n){
int e(a[i].e);
if(!dfn[e]){
tarjan(e);
low[u]=my_min(low[u],low[e]);
}
else
if(vis[e])
low[u]=my_min(low[u],dfn[e]);
}
if(low[u]==dfn[u]){
qlt++;
while(){
int tmp(zhan[top--]);
bl[tmp]=qlt;
vis[tmp]=;
size[qlt]++;
if(tmp==u)
break;
}
}
}
inline bool cmp(node a,node b){
if(cl[bl[a.id]]==cl[bl[b.id]])
return in[a.id]<in[b.id];
return cl[bl[a.id]]<cl[bl[b.id]];
}
queue<int>q;
int now(0x7fffffff),inf(0x7fffffff),fir;
int main(){
memset(pre,-,sizeof(pre));
n=read();
for(int i=;i<=n;i++){
hh[i].id=i;
target[i]=read();
if(target[i]==i){
die[i]=;
bl[i]=++qlt;
cl[qlt]=;
size[qlt]=;
ans_max++,ans_min++;
}
}
for(int i=;i<=n;i++){
if(!die[i]&&!die[target[i]])
insert(i,target[i]),in[target[i]]++;
}
for(int i=;i<=n;i++)
if(!dfn[i]&&!die[i])
tarjan(i);
for(int i=;i<=tot;i++){
int s(a[i].s),e(a[i].e);
s=bl[s],e=bl[e];
if(s!=e)
cl[s]=cl[e]=;
}
for(int i=;i<=qlt;i++){
if(cl[i]==&&size[i]>){
ans_max+=size[i]-;
ans_min+=(size[i]+)>>;
}
}
sort(hh+,hh++n,cmp);
for(int i=;i<=n;i++){
int tmp(hh[i].id);
if(cl[bl[tmp]]==&&!in[tmp]){
now=my_min(now,i);
continue;
}
if(cl[bl[tmp]]==&&in[tmp]){
fir=i;
break;
}
}
if(now!=inf){
ans_max+=n-fir+;
for(int i=now;i<fir;i++)
q.push(hh[i].id);
while(!q.empty()){
int k(q.front());
cl[bl[k]]=;
q.pop();
int tar(target[k]);
if(!die[tar]){
die[tar]=;
cl[bl[tar]]=;
ans_min++;
int kk(target[tar]);
in[kk]--;
if(!die[kk]&&!in[kk])
q.push(kk);
}
}
}
for(int i=;i<=cnt;i++)
if(cl[i])
ans_min+=(size[i]+)>>;
printf("%d %d",ans_min,ans_max);
}

[POI2008]枪战Maf的更多相关文章

  1. BZOJ 1124: [POI2008]枪战Maf

    1124: [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 617  Solved: 236[Submit][Status ...

  2. bzoj 1124 [POI2008]枪战Maf 贪心

    [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 741  Solved: 295[Submit][Status][Disc ...

  3. 【BZOJ1124】[POI2008]枪战Maf 贪心+思路题

    [BZOJ1124][POI2008]枪战Maf Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开 ...

  4. [POI2008]枪战Maf题解

    问题 C: [POI2008]枪战Maf 时间限制: 1 Sec  内存限制: 256 MB 题目描述 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺 ...

  5. BZOJ1124 [POI2008]枪战Maf[贪心(证明未完成)+拓扑排序]

    吐槽:扣了几个小时,大致思路是有了,但是贪心的证明就是不会, 死磕了很长时间,不想想了,结果码代码又不会码.. 深深体会到自己码力很差,写很多行还没写对,最后别人代码全一二十行,要哭了 以下可能是个人 ...

  6. bzoj1124[POI2008]枪战maf

    这代码快写死我了.....死人最多随便推推结论.死人最少,每个环可以单独考虑,每个环上挂着的每棵树也可以分别考虑.tarjan找出所有环,对环上每个点,求出选它和不选它时以它为根的树的最大独立集(就是 ...

  7. 【BZOJ】1124: [POI2008]枪战Maf

    题意 \(n(n < 1000000)\)个人,每个人\(i\)指向一个人\(p_i\),如果轮到\(i\)了且他没死,则他会将\(p_i\)打死.求一种顺序,问死的人最少和最多的数目. 分析 ...

  8. BZOJ1124 POI2008枪战Maf(环套树+贪心)

    每个点出度都为1,可以发现这张图其实是个环套树森林,树中儿子指向父亲,环上边同向. 首先自环肯定是没救的,先抬出去. 要使死亡人数最多的话,显然若一个点入度为0其不会死亡,而一个孤立的环至少会留下一个 ...

  9. BZOJ 1124: [POI2008]枪战Maf(构造 + 贪心)

    题意 有 \(n\) 个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪. 因此,对于不同的开枪顺序,最后死的人也不同. 问最 ...

随机推荐

  1. python 标准库 -- glob

    glob glob.glob() import glob l = glob.glob("/root/*") # 返回列表 print l # 输出如下 ['/root/databa ...

  2. jersery+jetty嵌入式restful的框架开发

    随着微服务的流程,越来越多的后台服务采用了restful api风格的开放API,jersery+jetty嵌入式变成了一个很好的选择, 我自己写了一个简单的框架,https://github.com ...

  3. .net 4.0 中的特性总结(二):默认参数、命名参数

    1.在方法定义的时候为参数指定一个默认值.调用方法的时候既可以像平时那样传入参数,也可以直接跳过不传入,这样的话,就使用默认值传到方法里.例如: 2.在之前版本的C#中,方法定义的参数顺序必须与方法调 ...

  4. ecshop屏蔽wap功能

    用手机打开ecshop网店,就会被重定向到mobile文件夹,如果打开wap功能,就能看到wap版的网站.但现在智能手机横行,iphone.安卓可以跟电脑一样浏览和购物,这个wap功能就有点鸡肋.现在 ...

  5. js中的匿名函数自执行

    随笔,java中因为有修饰符的存在,那就有private类的存在,js不一样,没有修饰词一说,因此为了防止全局变量的污染,js中就出现了匿名函数,直接上code,看到的人可以自己体会: (functi ...

  6. 【Android Developers Training】 4. 启动另一个Activity

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  7. 用Markdown优雅的写文章

    简介 Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. 简单点来说,Markdown是文本标记语言,在普通文本的基础上加了一些特殊标 ...

  8. UML 解析

    UML 解析 泛化 表示类与类之间的继承关系.接口与接口之间的继承关系: 实现 表示类对接口的实现 依赖 当类与类之间有使用关系时就属于依赖关系,不同于关联关系,依赖不具有"拥有关系&quo ...

  9. 今天get到的两个angular知识点

    angular 控制器$scope依赖注入的正确写法 <div ng-controller="ctrl"> {{name}} {{age}} <div ng-co ...

  10. 简单来说一下ui-route

    UI-Router被认为是AngularUI为开发者提供的最实用的一个模块,它是一个让开发者能够根据URL状态或者说是'机器状态'来组织和控制界面UI的渲染,而不是仅仅只改变路由(传统AngularJ ...