【牛客 - 373C】抓捕盗窃犯(连通图,思维,dfs 或 并查集)
題干:
鏈接:https://ac.nowcoder.com/acm/contest/373/C
來源:??途W(wǎng)
?
Q市發(fā)生了一起特大盜竊案。這起盜竊案是由多名盜竊犯聯(lián)合實(shí)施的,你要做的就是盡可能多的抓捕盜竊犯。
已知盜竊犯分布于?N?N個(gè)地點(diǎn),以及第?i?i個(gè)地點(diǎn)初始有?ai?ai名盜竊犯。
特別的是,對于每一個(gè)地點(diǎn)?u?u,都有一個(gè)固定的地點(diǎn)?v?v--當(dāng)前如果某個(gè)盜竊犯位于地點(diǎn)?u?u,在下一個(gè)時(shí)刻他會(huì)移動(dòng)到地點(diǎn)?v?v。
你需要通過初始時(shí)在某些點(diǎn)設(shè)置哨卡來捉住他們。
現(xiàn)在你可以在?M?M個(gè)地點(diǎn)設(shè)置哨卡,如果在某個(gè)地點(diǎn)設(shè)置哨卡,你可以抓獲在任一時(shí)刻經(jīng)過該地點(diǎn)的盜竊犯。
也就是說,哨卡存在的時(shí)間是無限長,但哨卡不能移動(dòng)。
輸入描述:
第一行兩個(gè)整數(shù)?N,M(1≤N,M≤105)?N,M(1≤N,M≤105)。 第二行?N?N個(gè)整數(shù)?a1a2...aN?a1a2...aN?(0≤a1,a2,...aN≤105)?(0≤a1,a2,...aN≤105),表示第?i?i個(gè)地點(diǎn)初始有?ai?ai名盜竊犯。 第三行?N?N個(gè)整數(shù)?v1v2...vN?v1v2...vN?(1≤v1,v2,...vN≤N)?(1≤v1,v2,...vN≤N),表示當(dāng)前處于地點(diǎn)?i?i的盜竊犯下一個(gè)時(shí)刻會(huì)移動(dòng)到地點(diǎn)?vi?vi。輸出描述:
輸出一行一個(gè)整數(shù)--能夠抓捕到的最大數(shù)量。示例1
輸入
復(fù)制
8 2 1 2 3 4 1 2 3 12 2 3 3 3 6 7 5 8輸出
復(fù)制
22說明
對于樣例一,一種可行的方案是:在地點(diǎn)3、地點(diǎn)8分別設(shè)置一個(gè)哨卡,此時(shí)答案為1+2+3+4+12=22示例2
輸入
復(fù)制
8 2 1 2 3 4 5 6 7 8 2 3 4 5 6 7 8 8輸出
復(fù)制
36說明
對于樣例二,一種可行的方案是:在地點(diǎn)2、地點(diǎn)8分別設(shè)置一個(gè)哨卡,此時(shí)答案為1+2+3+4+5+6+7+8=36解題報(bào)告:
注意到每個(gè)點(diǎn)的入度雖然不唯一,但是每個(gè)點(diǎn)的出度一定為1.也就是說只要這個(gè)圖是聯(lián)通的,那么一定能都匯集到同一個(gè)點(diǎn)上。所以我們只需要看看有多少個(gè)連通圖就可以,這個(gè)過程可以用dfs來實(shí)現(xiàn),也可以用并查集?。最后貪心出答案來。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 2e5 + 5; ll n,m; ll num[MAX]; int nt[MAX]; ll val[MAX]; int tot; bool vis[MAX]; ll tmp; vector<int> vv[MAX]; void dfs(int cur,int root) {vis[cur] = 1;tmp += num[cur];int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(vis[v] == 0) dfs(v,cur);} } int main() {cin>>n>>m;for(int i = 1; i<=n; i++) scanf("%lld",num+i);for(int i = 1; i<=n; i++) {scanf("%d",nt+i);vv[i].pb(nt[i]);vv[nt[i]].pb(i);}for(int i = 1; i<=n; i++) {if(!vis[i]) {tmp = 0;dfs(i,-1);val[++tot] = tmp;}}sort(val+1,val+tot+1);ll ans = 0;for(int i = tot; i>max(0LL,tot-m); i--) {ans += val[i];}printf("%lld\n",ans);return 0 ;}1WA了,,,最下面tot寫成了 tmp、、
總結(jié)
以上是生活随笔為你收集整理的【牛客 - 373C】抓捕盗窃犯(连通图,思维,dfs 或 并查集)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Valheim》控制台开启方法及常用指
- 下一篇: 【CodeForces - 471B】M