Byteazar the Dragon拥有N个小猪存钱罐。每一个存钱罐能够用相应的钥匙打开或者被砸开。Byteazar已经将钥匙放入到一些存钱罐中。现在已知每个钥匙所在的存钱罐,Byteazar想要买一辆小汽车,而且需要打开所有的存钱罐。然而,他想要破坏尽量少的存钱罐,帮助Byteazar去决策最少要破坏多少存钱罐。
任务:
写一段程序包括:
读入存钱罐的数量以及相应的钥匙的位置,求出能打开所有存钱罐的情况下,需要破坏的存钱罐的最少数量并将其输出。
输入样例#1: 复制
4 2 1 2 4
一开始在考虑 3->1<-2 这种情况并查集连起来却要打碎两个罐子 但是这种情况是不存在的。。。。
直接无脑并查集可以过
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f const int N=1000000+5; int f[N]; int find1(int x) { return f[x]==x?x:f[x]=find1(f[x]); } bool cmp(node a,node b) { return a.v>b.v; } void union1(int x,int y) { int a=find1(x); int b=find1(y); if(a!=b) f[a]=b; } int main() { int n;RI(n); rep(i,1,n)f[i]=i; rep(i,1,n) { int x;RI(x); union1(i,x); } int cnt=0; rep(i,1,n) if(f[i]==i) cnt++; cout<<cnt; return 0; }