[POI2008]枪战Maf
[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
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<queue> 6 using namespace std; 7 inline int read(){ 8 int sum(0); 9 char ch(getchar()); 10 for(;ch<'0'||ch>'9';ch=getchar()); 11 for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar()); 12 return sum; 13 } 14 int n; 15 struct edge{ 16 int s,e,n; 17 }a[1000001]; 18 int pre[1000001],tot; 19 inline void insert(int s,int e){ 20 a[++tot].s=s; 21 a[tot].e=e; 22 a[tot].n=pre[s]; 23 pre[s]=tot; 24 } 25 inline int my_max(int a,int b){ 26 return a>b?a:b; 27 } 28 inline int my_min(int a,int b){ 29 return a<b?a:b; 30 } 31 struct node{ 32 int id; 33 }hh[1000001]; 34 bool die[1000001]; 35 int target[1000001]; 36 int ans_min(0),ans_max(0); 37 int in[1000001]; 38 int low[1000001],dfn[1000001],zhan[1000001],bl[1000001],size[1000001]; 39 int cnt,top,qlt; 40 bool vis[1000001]; 41 int cl[1000001]; 42 inline void tarjan(int u){ 43 dfn[u]=low[u]=++cnt; 44 zhan[++top]=u; 45 vis[u]=1; 46 for(int i=pre[u];i!=-1;i=a[i].n){ 47 int e(a[i].e); 48 if(!dfn[e]){ 49 tarjan(e); 50 low[u]=my_min(low[u],low[e]); 51 } 52 else 53 if(vis[e]) 54 low[u]=my_min(low[u],dfn[e]); 55 } 56 if(low[u]==dfn[u]){ 57 qlt++; 58 while(1){ 59 int tmp(zhan[top--]); 60 bl[tmp]=qlt; 61 vis[tmp]=0; 62 size[qlt]++; 63 if(tmp==u) 64 break; 65 } 66 } 67 } 68 inline bool cmp(node a,node b){ 69 if(cl[bl[a.id]]==cl[bl[b.id]]) 70 return in[a.id]<in[b.id]; 71 return cl[bl[a.id]]<cl[bl[b.id]]; 72 } 73 queue<int>q; 74 int now(0x7fffffff),inf(0x7fffffff),fir; 75 int main(){ 76 memset(pre,-1,sizeof(pre)); 77 n=read(); 78 for(int i=1;i<=n;i++){ 79 hh[i].id=i; 80 target[i]=read(); 81 if(target[i]==i){ 82 die[i]=1; 83 bl[i]=++qlt; 84 cl[qlt]=0; 85 size[qlt]=1; 86 ans_max++,ans_min++; 87 } 88 } 89 for(int i=1;i<=n;i++){ 90 if(!die[i]&&!die[target[i]]) 91 insert(i,target[i]),in[target[i]]++; 92 } 93 for(int i=1;i<=n;i++) 94 if(!dfn[i]&&!die[i]) 95 tarjan(i); 96 for(int i=1;i<=tot;i++){ 97 int s(a[i].s),e(a[i].e); 98 s=bl[s],e=bl[e]; 99 if(s!=e) 100 cl[s]=cl[e]=1; 101 } 102 for(int i=1;i<=qlt;i++){ 103 if(cl[i]==0&&size[i]>1){ 104 ans_max+=size[i]-1; 105 ans_min+=(size[i]+1)>>1; 106 } 107 } 108 sort(hh+1,hh+1+n,cmp); 109 for(int i=1;i<=n;i++){ 110 int tmp(hh[i].id); 111 if(cl[bl[tmp]]==1&&!in[tmp]){ 112 now=my_min(now,i); 113 continue; 114 } 115 if(cl[bl[tmp]]==1&&in[tmp]){ 116 fir=i; 117 break; 118 } 119 } 120 if(now!=inf){ 121 ans_max+=n-fir+1; 122 for(int i=now;i<fir;i++) 123 q.push(hh[i].id); 124 while(!q.empty()){ 125 int k(q.front()); 126 cl[bl[k]]=0; 127 q.pop(); 128 int tar(target[k]); 129 if(!die[tar]){ 130 die[tar]=1; 131 cl[bl[tar]]=0; 132 ans_min++; 133 int kk(target[tar]); 134 in[kk]--; 135 if(!die[kk]&&!in[kk]) 136 q.push(kk); 137 } 138 } 139 } 140 for(int i=1;i<=cnt;i++) 141 if(cl[i]) 142 ans_min+=(size[i]+1)>>1; 143 printf("%d %d",ans_min,ans_max); 144 }
View Code
转载于:https://www.cnblogs.com/hzoi-mafia/p/7277750.html
[POI2008]枪战Maf相关推荐
- bzoj 1124 [POI2008]枪战Maf 贪心
[POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MB Submit: 741 Solved: 295 [Submit][Status][Di ...
- bzoj 1124: [POI2008]枪战Maf(贪心)
1124: [POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MB Submit: 713 Solved: 278 [Submit][Stat ...
- BZOJ 1124: [POI2008]枪战Maf(构造 + 贪心)
题意 有 \(n\) 个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪. 因此,对于不同的开枪顺序,最后死的人也不同. 问最 ...
- BZOJ 1124 [POI2008]枪战Maf 贪心+乱搞
题意:略. 方法:贪心+乱搞. 解析: 今天做的题里面最难的了- 分连通块进行考虑. 一个连通块最多死多少呢? 一个点 -> 死一个 一个环 -> 死环上点个数-1个 一个环加上内向树 - ...
- [BZOJ 1124][POI 2008] 枪战 Maf
1124: [POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MB Submit: 659 Solved: 259 [Submit][Stat ...
- html横向自动换行,HTML自动换行的问题
有时文本文字已经超过所在的区域,但是文字还是不自动换行 可以用强制换行 强制不换行div{ white-space:nowrap;} 自动换行div{ word-wrap:break-word; wo ...
- Annovar注释的突变文件转MAF对象
maftools可以读入Annovar注释的突变文件,生成成MAF对象,方便下游的突变分析. 1. 合并不同样本的突变文件,加上样本编号 原始的vcf文件经过Annovar软件注释后会生成注释好的.v ...
- bzoj1131[POI2008]Sta*
bzoj1131[POI2008]Sta 题意: 给出一个n个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大.n≤1000000. 题解: 两次dfs.第一次dfs维护子树的大小.节点 ...
- cf体验服_CF手游体验服_穿越火线枪战王者体验服申请_12月版本
1. 什么是<CF手游体验服>? <CF手游体验服>是<CF手游>对外开放的测试服务器,类似于其他游戏的体验服.任何重要的更新都会在体验服上优先进行,如新地图开放. ...
最新文章
- OpenCV4.4 CUDA编译与加速全解析
- 7 centos ssh 单机_虚拟机下CentOS7 开启SSH连接
- linux 杀死t状态进程,Linux下如何查杀stopped进程
- SingnalR 开发到生产部署闭坑指南
- 【启发式合并】【dfs】树数树(nowcoder 20107-C)
- WSDM2021 | 多交互注意力网络用于CTR预估中细粒度特征学习
- 饱和气压与温度的关系_高中物理讲义:固体液体与物态变化第3节《饱和汽与饱和汽压》...
- Linux环境中的帮助命令有,Linux下的帮助命令
- 自己做的一些练习题代码
- Ubuntu系统安装VMware Tools的简单方法
- Ubuntu /CentOS 设置开机启动,添加自定义系统服务,自定义开机启动
- 网页设计制作CSS实现隔行换色两种方法
- 【Qt】arm-none-eabi-gdb-py.exe由于找不到python27.dll 无法继续执行代码
- 航空系统c语言课程设计报告,c语言课程设计报告_航空订票系统西安郵電學院.doc...
- python content函数_python函数内容
- GTK+实现linux聊天室代码详解-clientr端
- CSS background-clip
- 联合分布(一):什么是概率分布
- 清华、北大、浙大的计算机课程资源集都在这里了
- 生活中的观察者偏见例子_消除人工智能第2部分中的偏见,解决性别和种族偏见...
热门文章
- office运行时错误,部分系统文件可能丢失或已损坏(错误代码:0x80040154)
- springboot+微信小程序“微印象”在线打印预约系统的设计与实现毕业设计源码061642
- 南卫理公会大学 计算机排名,2019-2020南卫理公会大学世界排名多少【QS最新第701-750名】...
- 遥感相关专业英语词汇汇总
- 云麦体脂秤华为体脂秤_华为智能体脂秤(蓝牙版),会是良心之选吗?
- 2021-09-07体脂秤模块用来做什么?开发八电极体脂秤方案
- maven pc配置要求_竞速游戏《F1 2019》PC配置要求 GTX 1660ti即可畅玩
- Sketch(三)——插件
- 【 58沈剑 架构师之路】究竟啥才是互联网架构“高并发”
- 交互题 XOR Guessing