題目連接 :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 }