P3472 [POI2008]MAF-Mafia
P3472 [POI2008]MAF-Mafia
解法
不难发现,这个题目建图后出现的是一个基环树森林+一堆环,因为每个点仅有一条出边。
大概长这样:

对于最大,最小值,我们分开考虑。
最大值
可以看到,当我们缩点后,对于一个没有入度的点,其对答案的贡献为1。
因为当一个点入度为0时,其要么原本是个环,要么原本也是一个点:
当其是一个环时,可以通过一些击杀顺序从而使环仅剩一个点。
当其是一个点时,没有点可以杀掉他。
而其他点都可以通过一些奇妙的顺序被杀掉。
最小值
我们观察,如果是一个单独的环,其对答案的贡献应该是\(siz/2\)
我们再在一颗基环树上观察:
可以得到,入读为\(0\)的点是不会被杀的,那么我们将其入队,并统计答案。
然后入读为\(0\)的点所指向的点一定会被杀,当我们将队头取出时,将其所指向的点杀掉,再将其指向的点所指向的点的入读减\(1\),当其入度为\(0\)时,便将其入队,并统计答案。
这里就相当于做了一次变形的拓扑排序。
然后我们再去找环:
当这个环上至少有一个点被杀时,那么这个环就变成链,再拓扑排序的时候已经计算过了不管。
如果没有点被杀,则和单独一个环的情况一样。
CODE
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e6+33;
inline ll read_int(){
ll a=0;bool f=0;char g=getchar();
while(g<'0'||'9'<g) {if(g=='-') f=1;g=getchar();}
while('0'<=g&&g<='9') a=a*10+g-'0',g=getchar();
return f ? -a : a;
}
inline void write(ll a,bool b=1){
if(a<0) a=-a,putchar('-');
int lin[30],top=0;
while(a) lin[++top]=a%10,a/=10;
if(top==0) lin[++top]=0;
while(top) putchar(lin[top--]+'0');
if(b) putchar('\n');
}
int n;
int t[maxn],rd[maxn];
int tme,low[maxn],dfn[maxn],zan[maxn],top;
int bel[maxn],siz[maxn],tot;
int vis[maxn];
inline void tarjian(int s){
low[s]=dfn[s]=++tme;
zan[++top]=s;
if(!vis[t[s]]){
if(dfn[t[s]]) low[s]=min(low[s],dfn[t[s]]);
else tarjian(t[s]),low[s]=min(low[s],low[t[s]]);
}
vis[s]=1;
if(low[s]==dfn[s]){
tot++;
while(zan[top]!=s){
siz[tot]++;
bel[zan[top]]=tot;
top--;
}
siz[tot]++;
bel[zan[top]]=tot;
top--;
}
}
int maxx=0,rd_[maxn];
inline void suodian(){
for(int i=1;i<=n;i++){
if(rd[i]==0) maxx++;
if(bel[i]==bel[t[i]]){
if(i==t[i]) rd_[bel[i]]=1;
continue;
}
rd_[bel[t[i]]]++;
}
for(int i=1;i<=tot;i++){
if(rd_[i]) continue;
if(siz[i]==1) continue;
maxx+=1;
}
maxx=n-maxx;
}
int die[maxn],dee[maxn];
inline void read(){
n=read_int();
for(int i=1;i<=n;i++) t[i]=read_int(),rd[t[i]]++;
for(int i=1;i<=n;i++) if(vis[i]==0) tarjian(i);
suodian();
queue<int> p;
ll minn=0;
for(int i=1;i<=n;i++){
if(rd[i]) continue;
minn++;
p.push(i);
}
while(!p.empty()){
int s=p.front();
p.pop();
if(die[t[s]]) continue;
die[t[s]]=1;
if((--rd[t[t[s]]])==0) p.push(t[t[s]]),minn++;
}
for(int i=1;i<=n;i++) dee[bel[i]]|=die[i];
for(int i=1;i<=tot;i++) if(dee[i]==0&&siz[i]>1) minn+=siz[i]/2;
cout<<n-minn<<" "<<maxx;
}
int main (){
// freopen("maf.in","r",stdin);
// freopen("maf.out","w",stdout);
read();
// while(1) getchar();
}
后记
模拟赛没写出来,木有判断自环。。。。
P3472 [POI2008]MAF-Mafia的更多相关文章
- BZOJ 1124: [POI2008]枪战Maf
1124: [POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 617 Solved: 236[Submit][Status ...
- [POI2008]枪战Maf
[POI2008]枪战Maf 题目 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的 ...
- bzoj 1124 [POI2008]枪战Maf 贪心
[POI2008]枪战Maf Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 741 Solved: 295[Submit][Status][Disc ...
- 【BZOJ1124】[POI2008]枪战Maf 贪心+思路题
[BZOJ1124][POI2008]枪战Maf Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开 ...
- [POI2008]枪战Maf题解
问题 C: [POI2008]枪战Maf 时间限制: 1 Sec 内存限制: 256 MB 题目描述 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺 ...
- BZOJ1124 [POI2008]枪战Maf[贪心(证明未完成)+拓扑排序]
吐槽:扣了几个小时,大致思路是有了,但是贪心的证明就是不会, 死磕了很长时间,不想想了,结果码代码又不会码.. 深深体会到自己码力很差,写很多行还没写对,最后别人代码全一二十行,要哭了 以下可能是个人 ...
- 枪战Maf[POI2008]
题目描述 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的人也不同. 输入 输入n人 ...
- bzoj1124[POI2008]枪战maf
这代码快写死我了.....死人最多随便推推结论.死人最少,每个环可以单独考虑,每个环上挂着的每棵树也可以分别考虑.tarjan找出所有环,对环上每个点,求出选它和不选它时以它为根的树的最大独立集(就是 ...
- 【BZOJ】1124: [POI2008]枪战Maf
题意 \(n(n < 1000000)\)个人,每个人\(i\)指向一个人\(p_i\),如果轮到\(i\)了且他没死,则他会将\(p_i\)打死.求一种顺序,问死的人最少和最多的数目. 分析 ...
- BZOJ1124 POI2008枪战Maf(环套树+贪心)
每个点出度都为1,可以发现这张图其实是个环套树森林,树中儿子指向父亲,环上边同向. 首先自环肯定是没救的,先抬出去. 要使死亡人数最多的话,显然若一个点入度为0其不会死亡,而一个孤立的环至少会留下一个 ...
随机推荐
- signal-slot:python版本的多进程通信的信号与槽机制(编程模式)的库(library) —— 强化学习ppo算法库sample-factory的多进程包装器,实现类似Qt的多进程编程模式(信号与槽机制) —— python3.12版本下成功通过测试
什么是 Qt signal-slot库项目地址: https://github.com/alex-petrenko/signal-slot 该库实现的主要原理: 要注意这个项目的library只是对原 ...
- 人类社会学:“重男轻女"思潮的比重,从多孩男女性别比角度思考
参考资料: https://baijiahao.baidu.com/s?id=1780697594797038227 https://mbd.baidu.com/newspage/data/video ...
- 《Bitcoin: A Peer-to-Peer Electronic Cash System》 中本聪写的比特币白皮书
网址: https://bitcoin.org/bitcoin.pdf =============================================================
- Ubuntu系统中CUDA套件nvvp启动后报错Unable to make protected void java.net.URLClassLoader.addURL(java.net.URL) accessible: module java.base does not "opens java.net" to unnamed module @380fb434
最近在看cuda方面的内容,需要对cuda代码做一些性能分析,于是需要使用nvvp,但是启动nvvp后报错:Caused by: java.lang.reflect.InaccessibleObjec ...
- 在oracle中将一行字符串拆分成多行
例如,有如下一张表,表名为bk_test.插入了以下数据: CREATE TABLE BK_TESK(id varchar2(10),s varchar2(20)); insert into BK_T ...
- Apache DolphinScheduler 在奇富科技的首个调度异地部署实践
奇富科技(原360数科)是人工智能驱动的信贷科技服务平台,致力于凭借智能服务.AI研究及应用.安全科技,赋能金融机构提质增效,助推普惠金融高质量发展,让更多人享受到安全便捷的金融科技服务.作为国内领先 ...
- [NOIP2010 提高组] 关押罪犯 - 洛谷
P1525 [NOIP2010 提高组] 关押罪犯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 种类并查集 #include <bits/stdc++.h> #def ...
- 微服务全链路跟踪:jaeger坑之NoSuchMethodError: io.jaegertracing.agent.thrift.Agent$Client.sendBaseOneway
在jaeger使用过程中遇到了一个奇怪的问题,本来jaeger运行的好好的,jaeger配置与依赖都没动,就上了一个版本,结果jaeger就没上报监控数据了,由于生产上没打印info日志,后面在本地试 ...
- 1000T的文件怎么能快速从南京传到北京?最佳方案你肯定想不到
今天刷面试题看到一个有意思的面试题, 1000T的文件怎么能以最快速度从南京传到北京? 网络传输 首先我们考虑通过网络传输,需要多长时间. 我特地咨询了在运营商工作的同学,目前带宽: 家庭宽带下行最大 ...
- 基于docker搭建单机测试ELK
说明:本次使用的windows系统,利用vm进行安装虚拟机,安装的只是单测试单机版elk. 一.下载vm 自行官网下载 二.安装centos7系统 自己有现成的镜像跳过,没有自行查找资料完成 三.进行 ...