Description

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

Input

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

Solution

其实就是一个基环树森林

显然可以把每个基环树分开,然后分情况讨论。

环:死最多:len-1,死最少:[len/2]上取整

自环:最多最少都是1

树:死最多:只剩下叶子。死最少:叶子不会死,然后父亲一定死,就贪心地让父亲就别打死爷爷。这样一定不会更劣。大概就是隔一层打一层

基环树:死最多:只剩下叶子。死最少:先把每个子树按照树的打法打完,然后基环可能会变成若干个链,每个链都是:len/2下取整。剩环的话,那么和环(或者自环)一样。

树和基环树的叶子往上打就是拓扑排序。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=+;
int n;
struct node{
int nxt,to;
}e[*N];
int hd[N],cnt=;
int du[N];//you xiang
int huan;//len of huan
bool on[N];//on the huan
bool vis[N];
bool die[N];
bool go[N];
bool has[N];
int to[N];
int mxans,mians;
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
bool fl;
int sta[N],top;
vector<int>mem;
int in[N];//in the sta
void dfs(int x,int in_edge){
// cout<<" dfs "<<x<<" "<<endl;
sta[++top]=x;
vis[x]=;in[x]=;
mem.push_back(x);
for(int i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(i==(in_edge^)) continue;
if(vis[y]){
if(in[y]&&!fl){
// cout<<" fin "<<y<<endl;
fl=true;
int z;//=sta[top];
do{
z=sta[top];
on[z]=;in[z]=;
huan++;
top--;
}while(z!=y);
}
}
else dfs(y,i);
}
if(sta[top]==x) in[x]=,top--;
}
int q[N],l,r;
int len;//len of lian
void wrk(int x,int pre){//dfs on the huan
go[x]=;
//cout<<x<<" "<<pre<<endl;
for(int i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==pre) continue;
if(go[y]) continue;
if(on[y]){
//cout<<" y "<<y<<endl;
if(die[y]){
mians+=len/;len=;
}else len++;
wrk(y,x);
}
}
}
void topo(){
len=;
l=,r=;
//cout<<" huan "<<huan<<endl;
//cout<<" mem "<<mem.size()<<endl;
///cout<<mians<<endl;
for(int i=0;i<mem.size();i++){
int id=mem[i];
//cout<<id<<" "<<on[id]<<" "<<in[id]<<endl;
if(du[id]==) q[++r]=id,has[id]=;
}
if(huan==||huan>) mxans+=mem.size()-max(r,);
else mxans+=mem.size()-r;
bool kil=false;
int st;
while(l<=r){
int x=q[l++];
//cout<<" x "<<x<<endl;
//if(has[to[x]]) continue;
if(!die[x]){
if(!die[to[x]]) mians++,die[to[x]]=;
if(on[to[x]])kil=,st=to[x];
}
du[to[x]]--;
if(du[to[x]]==){
q[++r]=to[x];
}
}
if(kil){
//cout<<" kil "<<st<<endl;
//cout<<mians<<endl;
wrk(st,);
//cout<<" len "<<len<<endl;
mians+=len/;
}
else{
mians+=huan-(huan/);
}
} int main(){
scanf("%d",&n);int y;
for(int i=;i<=n;i++){
scanf("%d",&y);to[i]=y;
add(i,y);add(y,i);du[y]++;
}
for(int i=;i<=n;i++){
if(!vis[i]){
//cout<<" another "<<i<<endl;
fl=false;
huan=;
mem.clear();
dfs(i,);
topo();
//cout<<" mians "<<mians<<" mxans "<<mxans<<endl;
}
}
cout<<mians<<" "<<mxans<<endl;
return ;
} /*
Author: *Miracle*
Date: 2018/10/14 19:28:35
*/

[POI2008]MAF-Mafia的更多相关文章

  1. BZOJ 1124: [POI2008]枪战Maf

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

  2. [POI2008]枪战Maf

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

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

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

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

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

  5. [POI2008]枪战Maf题解

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

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

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

  7. 枪战Maf[POI2008]

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

  8. bzoj1124[POI2008]枪战maf

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

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

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

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

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

随机推荐

  1. Sublime Text3添加右键

    在Sublime Text3安装目录下新建一个文件 sublime_addright.inf 文件内容: [Version] Signature="$Windows NT$" [D ...

  2. C、C++字符操作归总

    1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度 ...

  3. Python接口测试实战2 - 使用Python发送请求

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  4. katalon系列十一:Katalon Studio在Jenkins持续集成

    以下在WIN10上运行正常.安装准备:一.安装Katalon Studio二.安装Jenkins三.获取Katalon命令行运行命令:点击工具栏的‘Build CMD’按钮,选择测试集以及其他选项:选 ...

  5. Mybatis-Plus的填坑之路 - Lynwood/wunian7yulian

    目录 Mybatis-Plus 我来填坑~ 目录 一.简单介绍 官方说明 : 成绩: 最新版本: 开发层面MyBatis-Plus特色 Mybatis-Plus中的Plus 二.MP的特性 三.MP框 ...

  6. Python基础入门(迭代器和生成器)

    1 Python迭代器 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退. 迭代器有两个基本的方法:iter() 和 ...

  7. 写一个脚本批量转换项目中GB2312编码的文件为UTF-8编码

    #!/bin/bash convert_file() { for file in `find .` do if [[ -f $file ]] then if [[ ${file##*.} == lua ...

  8. 复利计算器4.0之再遇JUnit

    复利计算器4.0之再遇JUnit 前言    虽然之前的复利计算器版本已经尝试过使用JUnit单元测试,但由于没有系统性地学习过JUnit的使用,用得并不好,主要问题表现在测试的场景太少,并没有达到测 ...

  9. sql主表分页查询关联子表取任意一条高效方案

    有个业务场景,主表中一条数据,在子表中有多条详情数据.对数据进行展示的时候,产品希望随意拿一条子表的数据关联展示出来,用了很多方案,但是都不够好. sql查询取子表任意一条,多个字段的方案 最终找到一 ...

  10. Alpha 冲刺8

    队名:日不落战队 安琪(队长) 今天完成的任务 登录的数据post. okhttp学习第二弹. 明天的计划 okhttp学习第三弹. 个人信息界面数据get. 还剩下的任务 个人信息数据get. 遇到 ...