并查集 牛客练习赛41 C抓捕盗窃犯

题目连接 :https://ac.nowcoder.com/acm/contest/373/Cc++

题意,初始每个城市都有一伙盗贼,没过一个时刻盗贼就会逃窜到另外一个城市,你能够在m个城市设置监察站,会逮捕全部通过该城市的盗贼spa

分析:仔细分细题目,由于每一个城市的盗贼都是流动的,这就可能会造成环,而若是成环的话,在环所在任一城市均可以把这批城市的所有盗贼逮捕,就不须要再环上设多个监察站了,进一步推广,由于能够本身往本身的城市跑,因此也有多是链,而链也是知足设一个监察站能够逮捕全部code

天然想到引入并查集,用map来保存blog

 1 #include <bits/stdc++.h>
 2 using  namespace std;  3 typedef long long ll;  4 const int maxn=1e5+7;  5 const int mod=1e9+7;  6 ll a[maxn],v[maxn];  7 ll par[maxn];  8 ll rnk[maxn];  9 ll c[maxn]; 10 bool cmp(const ll &a,const ll &b){ 11     return a>b; 12 } 13 void init(){ 14     for(ll i=0;i<maxn;i++) par[i]=i,rnk[i]=0; 15 } 16 ll find(ll x){ 17     if(par[x]==x){ 18         return x; 19  } 20     else{ 21         return par[x]=find(par[x]); 22  } 23 } 24 void unite(ll x,ll y){ 25     x=find(x);y=find(y); 26     if(x==y) return ; 27     if(rnk[x]<rnk[y]){ 28         par[x]=y; 29     }else { 30         par[y]=x; 31         if(rnk[x]==rnk[y]) rnk[x]++; 32  } 33 } 34 bool same(ll x,ll y){ 35     return find(x)==find(y); 36 } 37 int main(){ 38     ll n,m;scanf("%lld%lld",&n,&m); 39  init(); 40     for(int i=1;i<=n;i++){ 41         scanf("%lld",&a[i]); 42  } 43     for(int i=1;i<=n;i++){ 44         scanf("%lld",&v[i]); 45  unite(i,v[i]); 46  } 47     map<ll,ll> ans; 48     map<ll,ll>::iterator ite; 49     for(ll i=1;i<=n;i++){ 50         ans[find(i)]+=a[i]; 51  } 52     //for(int i=1;i<=n;i++) cout<<find(i)<<" ";
53     int j=0; 54     for(ite=ans.begin();ite!=ans.end();++ite){ 55         c[j++]=ite->second; 56  } 57     sort(c,c+ans.size(),cmp); 58     ll cnt=0; 59     for(ll i=0;i<m&&i<ans.size();i++){ 60     cnt+=c[i];}//cout<<c[i]<<endl;}
61     cout<<cnt<<endl; 62     return 0; 63 }
相关文章
相关标签/搜索