题目描述

Byteazar有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar已经把每个存钱罐的钥匙放到了某些存钱罐里. Byteazar 现在想买一台汽车于是要把所有的钱都取出来. 他想尽量少的打破存钱罐取出所有的钱,问最少要打破多少个存钱罐.

输入格式

第一行一个整数 N (1 <= N <= 1.000.000)表示存钱罐的总数.

接下来每行一个整数,第 i+1行的整数代表第i个存钱罐的钥匙放置的存钱罐编号.

输出格式

一个整数表示最少打破多少个存钱罐.


分析题目性质。

题目给了若干个单向关系,我们可以依照这个建出一张有向图。那么显然,只要我们有了一个存钱罐的钥匙,那这个强连通分量里的所有存钱罐都可以打开了。那么我们对图中所有强连通分量进行缩点,入度>0的点就通过其它点得到钥匙,入度为0的点我们就砸开它。所以答案就是入度为0的强连通分量个数。

强连通分量用Tarjan来求,时间复杂度为O(N)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define maxn 1000001
using namespace std;vector<int> to[maxn];
int dfn[maxn],low[maxn],tot;
int col[maxn],ind[maxn],cnt;
int stack[maxn],top;
bool instack[maxn];
int n,ans;inline int read(){register int x(0),f(1); register char c(getchar());while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}void tarjan(int u){dfn[u]=low[u]=++tot,stack[++top]=u,instack[u]=true;for(register int i=0;i<to[u].size();i++){int v=to[u][i];if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);else if(instack[v]) low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]){int v; cnt++;do{ v=stack[top--],instack[v]=false; col[v]=cnt; }while(v!=u);}
}int main(){n=read();for(register int i=1;i<=n;i++) to[read()].push_back(i);for(register int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);for(register int i=1;i<=n;i++){for(register int j=0;j<to[i].size();j++){int v=to[i][j];if(col[i]!=col[v]) ind[col[v]]++;}}for(register int i=1;i<=cnt;i++) if(!ind[i]) ans++;printf("%d\n",ans);return 0;
}

转载于:https://www.cnblogs.com/akura/p/10957165.html

[Poi2005]Piggy Banks小猪存钱罐相关推荐

  1. 洛谷·[POI2005]SKA-Piggy Banks 小猪存钱罐【Tarjan 并查集

    初见安~这里是传送门:洛谷P3420 题目描述3 Byteazar the Dragon has NN piggy banks. Each piggy bank can either be opene ...

  2. [Poi0504]Piggy Banks小猪存钱罐 (并查集)

    Byteazar 有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar 已经把每个存钱罐的钥匙放到了某些存钱罐里. Byteazar 现在想买一台汽车于是要把所有的钱都取出来. ...

  3. Taran 缩点【bzoj1529】[POI2005]ska Piggy banks

    [bzoj1529][POI2005]ska Piggy banks Description Byteazar 有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar 已经把每个 ...

  4. BZOJ 1529: [POI2005]ska Piggy banks( 并查集 )

    每一连通块砸开一个就可以拿到所有的钱, 所以用并查集求连通块数 ------------------------------------------------------------------- ...

  5. [bzoj1529][POI2005]ska Piggy banks 大水题

    1529: [POI2005]ska Piggy banks Time Limit: 5 Sec  Memory Limit: 64 MB [Submit][Status][Discuss] Desc ...

  6. bzoj1529: [POI2005]ska Piggy banks

    Description Byteazar 有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar 已经把每个存钱罐的钥匙放到了某些存钱罐里. Byteazar 现在想买一台汽车于 ...

  7. BZOJ_P1529 [POI2005]ska Piggy banks(并查集)

    BZOJ传送门 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1062 Solved: 494 [Submit][Status][Discuss] Des ...

  8. BZOJ1529ska Piggy banks

    1529: [POI2005]ska Piggy banks Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1065 Solved: 496 Descri ...

  9. 合根植物,小猪存钱罐(python)

    文章目录 合根植物 分析 运行代码 通过截图 小猪存钱罐(Piggy Banks) 分析 运行代码 超时截图(超时了) 合根植物 w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方 ...

最新文章

  1. JQ+ajax 提交表单不跳转页面
  2. 一点想法--- 做一个轻便的程序编辑器
  3. 乘客公交车上被盗 司机该不该停车闭门等警察
  4. Python IDLE或Python Shell不支持中文编码的解决方案
  5. Oracle清除缓存的命令,Oracle的get命令
  6. string转成对象_详解Java I/O流(五),对象序列化
  7. 【华为云技术分享】【论文阅读】增量式物体检测
  8. C语言分支语句与循环语句较为全面的总结,快来看呀!!
  9. 2012总结--目录
  10. 软件2班36人[扑林作]
  11. 揭秘Mindscape WPF Elements 5新特性
  12. 工作流集成表单的过程
  13. win10计算机快捷键设置,win10计算器快捷键设置_w10电脑计算器快捷键怎么添加-win7之家...
  14. UFS 3.1协议分析(第六章) -- UFS电气信号
  15. 2015/7/22 成交量怀疑 会不会是在吸引上方的套牢盘割肉呢
  16. 读完这篇文章,你就是下一个时间管理大师。
  17. 如何下载VMWare虚拟机如何安装VMWare详细教程
  18. 用文氏图来理解卷积神经网络如何决定提取哪些特征
  19. 今日早报,365资讯简报12条,热点新闻早知道
  20. vs上C/C++并行计算#pragma omp

热门文章

  1. python 产生小数等步长数据
  2. java实现lz77算法实例_数据压缩算法---LZ77算法 的分析与实现
  3. 人工智能导论期末复习
  4. 【Django-Meeting系统】简单的JS 正则验证手机号码JavaScript--20220715
  5. 阿里云RRpc请求消息普适发送端
  6. cisco 3560 QOS配置
  7. SLAM基础——舒尔补介绍
  8. 新的一步,从现在开始
  9. 笔记:以太网帧格式及其type取值说明
  10. 关于e^x的部分公式和约算方法