此題出自:
星際飛行員alice在一次航行中遭遇了時空亂流,時空亂流將導致alice乘坐的飛船在n個位面之間穿梭。星際宇航局管理員bob收到了alice的求救訊號,決定在某些位面上設立監測站,當alice進入某個已經設立監測站的位面後,她會立即被拯救。
由於不同位面情況不同,設立監測站的花費也不相同。在第i個位面設立監測站,所需花費為ci。
時空亂流已經被星際宇航局完全勘測,每個位面都有通往某個位面的通道,如果第i個位面沒有監測站,alice會前往第ai個位面。(若ai=i則會停留在當前位面)
bob並不知道alice的初始位置,他必須考慮所有可能的情況,並使用盡可能少的花費,確保能從時空亂流中救出alice。
你能幫bob計算出至少要花費多少,才能確保能救出alice嗎?
第一行乙個整數t,表示有t組測試資料。每組測試資料,第一行乙個整數n (1≤n≤200000),表示有n個位面。
第二行n個整數ci(1≤ci≤10000),表示在第i個位面設立監測站的花費ci。
第三行n個整數ai(1≤ai≤n),表示第i個位面通往第ai個位面。
每組資料輸出乙個整數,表示最小花費。
351 2 3 2 10
1 3 4 3 3
41 10 2 10
2 4 2 2
71 1 1 1 1 1 1
2 2 2 3 6 7 6
3102
輸入資料較多,請使用scanf/printf這題我一開始看想到的是並查集,但是錯了幾次才發現並查集並不能做這道題,因為這裡的資料是單向的,並且並查集處理不了環,所以下一步想到強連通將環縮點,再判斷每點的出度是否為零,為零的點就是必須要設監測站的地方
#include #include #include #include #include #include #include #include #include #include #define inf 0x3f3f3f3f
using namespace std;
const int maxn=200005;
vectore[maxn];
int w[maxn],val[maxn],out[maxn],vis[maxn],dfn[maxn],low[maxn];
int num,sum,color[maxn];
stacks;
void tarjan(int u)
else if(vis[v])
}if(dfn[u]==low[u])
while(t!=u);
}}int main()
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(val,0,sizeof(val));
memset(w,0,sizeof(w));
for(int i=1; i<=n; i++)
for(int i=1; i<=n; i++)
for(int i=1; i<=n; i++)
memset(out,0,sizeof(out));
for(int i=1;i<=n;i++)
}int ans=0;
for(int i=1;i<=sum;i++)
printf("%d\n",ans);
}return 0;
}
模板 強連通縮點
直接給他縮點然後求新的圖的完整版 c2 u 表示縮點後的u點這個環上的點實際上是哪些 g3 u 表示縮點後的u點的出邊 還是一樣,要記得先處理入鏈。可以讓這個圖好看一點但是沒啥鳥用 入鏈可能會有一些特別的性質,當然假如入鏈沒有特別性質也可以直接縮點。不對其實直接縮點就可以了,入鏈還是新圖的入鏈,環是...
hdu 2767 強連通縮點
補最少的邊成強連通圖。縮點後成dag,max即為所求。include include include define mn 20020 define me 200010 define mm a,b as void add e int i,int u,int v void tarjan int i el...
hdu 4635 強連通縮點
多校聯賽4的一道題,給乙個有向圖,問最多加多少條邊後仍然不是強聯通,以前總會遇到問最少加幾條邊讓圖成乙個強連通圖,比賽時自己就找到了答案,當時想著新增最多的邊後一定是將原來的圖連成兩個強連通分量,而兩個強連通分量間的邊最多是兩個聯通分量的點數之積,再加上每個聯通分量內部的點的邊數就是所有的邊數,再減...