題意本題給出圖中的n個節點,同時給出兩種操作:1、在兩個節點間連線一條邊,使得兩個節點都有水,邊權已給出;2、消耗 wi 為第 i 個節點供水,題目要求用以上兩種操作,使得消耗最小且每個節點都有水。實質上可以轉化為最小生成樹問題。東東在老家農村無聊,想種田。農田有 n 塊,編號從 1~n。種田要灌溉,眾所周知東東是乙個魔法師,他可以消耗一定的 mp 在一塊田上施展魔法,使得黃河之水天上來。他也可以消耗一定的 mp 在兩塊田的渠上建立傳送門,使得這塊田引用那塊有水的田的水。 (1<=n<=3e2)
黃河之水天上來的消耗是 wi,i 是農田編號 (1<=wi<=1e5)
建立傳送門的消耗是 pij,i、j 是農田編號 (1<= pij <=1e5, pij = pji, pii =0)
求東東為所有的田灌溉的最小消耗
input
第1行:乙個數n
第2行到第n+1行:數wi
第n+2行到第2n+1行:矩陣即pij矩陣
output
東東最小消耗的mp值
example input45
4430 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
example output
9
本題明顯是一道最小生成樹問題,但是不好處理每個節點上的「黃河之水天上來」問題。此時只需要新增乙個 0 號節點即可,wi 可以理解為是 0 號節點與 i 號節點之間的邊權。之後再使用kruskal演算法找到最短路徑長度即可。
此處的kruskal演算法借助並查集實現。首先將所有邊按權值由小到大排序,可以借助小根堆實現。隨後每次取邊,若這條邊的頭尾節點不在乙個並查集內,就可以選用這條邊,否則不選。由於本題新增了節點 0 ,所以當選定邊數為 n 條是就可以結束迴圈了,求出選定邊權總和就是最小消耗值。
本題**可以用於儲存kruskal演算法模板,效果較好。
#include
#include
#define maxn 100005
using
namespace std;
struct road};
priority_queue a;
//自定資料型別優先佇列
int fa[
305]
;int
getfa
(int n)
return fa[n];}
void
unity
(int x,
int y)
intmain
(int argc,
char
** ar**)
int n,cnt =
0,ans =0;
road temp;
cin >> n;
for(
int i =
1; i <= n; i++
)for
(int i =
1; i <= n; i++)}
}while
(cnt < n)
} cout << ans;
return0;
}```
掌握魔法 東東 I(最小生成樹kruskal)
東東在老家農村無聊,想種田。農田有 n 塊,編號從 1 n。種田要灌氵 眾所周知東東是乙個魔法師,他可以消耗一定的 mp 在一塊田上施展魔法,使得黃河之水天上來。他也可以消耗一定的 mp 在兩塊田的渠上建立傳送門,使得這塊田引用那塊有水的田的水。1 n 3e2 黃河之水天上來的消耗是 wi,i 是農...
會魔法的東東 最小生成樹問題
東東在老家農村無聊,想種田。農田有 n 塊,編號從 1 n。種田要灌氵 眾所周知東東是乙個魔法師,他可以消耗一定的 mp 在一塊田上施展魔法,使得黃河之水天上來。他也可以消耗一定的 mp 在兩塊田的渠上建立傳送門,使得這塊田引用那塊有水的田的水。1 n 3e2 黃河之水天上來的消耗是 wi,i 是農...
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...