bzoj 1529
2016-04-07 18:42
375 查看
【bzoj1529】[POI2005]ska Piggy banks
2014年5月17日8550
Description
Byteazar 有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar 已经把每个存钱罐的钥匙放到了某些存钱罐里. Byteazar 现在想买一台汽车于是要把所有的钱都取出来. 他想尽量少的打破存钱罐取出所有的钱,问最少要打破多少个存钱罐.
Input
第一行一个整数 N (1 <= N <= 1.000.000) – 表示存钱罐的总数. 接下来每行一个整数,第 i+1行的整数代表第i个存钱罐的钥匙放置的存钱罐编号.
Output
一个整数表示最少打破多少个存钱罐.
Sample Input
42
1
2
4
Sample Output
2In the foregoing example piggy banks 1 and 4 have to be smashed.
解题思路:原本想用tarjan来做,看到黄学长说超空间。又看到并查集的做法,神奇啊。。。
好像最小点基可以用并查集来求。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int f[1000001];
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-')f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}
return x*f;
}
int find(int o)
{
if (f[o]!=o) f[o]=find(f[o]);
return f[o];
}
int main()
{
n=read();
for (int i=1;i<=n;++i)
f[i]=i;
for (int i=1;i<=n;++i)
{
int u=read();
int x1=find(u); int x2=find(i);
if (x1!=x2)
{
f[x1]=x2;
}
}
int ans=0;
for (int i=1;i<=n;++i)
if (find(i)==i)
ans+=1;
printf("%d",ans);
}
相关文章推荐
- HashMap与ConcurrentHashMap的区别(转)
- 记录《精通CSS:高级Web标准解决方案》学习过程
- Unity3D for VR 学习(2): 暴风魔镜框架探索
- [线段树] BZOJ 4491 我也不知道题目名字是什么
- ffmpeg 和 x264的参数对照
- c语言基础概念(2)
- 扣丁学堂笔记第26天云平台、Git与Linux
- 11、Mysql表的分区实现
- UVA_793_Network Connections
- Jquery的extend
- 重载和重写
- Linux Namespaces机制
- Hive安装及使用攻略
- Unity3D for VR 学习(1): 又一个新玩具 暴风魔镜 4(Android)
- [LCT 线性模方程] BZOJ 2759 一个动态树好题
- note: candidates are: virtual void CHandle::OnExcute(int, char*, int&, char*, int&)
- 带中文的路径导致NSURL初始化一直为null的问题
- 1、汇编学习之进制转换
- open gop的提升画质很有限,建议默认值,即为关闭gop
- Git基本操作