東東在老家農村無聊,想種田。農田有 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
output
9這道題的目的是為了給所有的農田都灌溉上水,我們可以將題目中的「黃河之水天上來」看作乙個超級原點,將這個原點和所有的農田看作是圖中乙個個點,點與點之間的邊的權值則為「在田上施展魔法,使得黃河之水天上來」所消耗的mp或是「兩塊田的渠上建立傳送門」所消耗的mp,於是這道題便轉化成了一道求圖的最小生成樹的題目。
採用 kruskal 演算法求解最小生成樹。kruskal演算法的思想是,將圖中所有的邊按照權重排序,依次取出最小的邊,邊能夠加入到最小生成樹中的條件是這條邊不會與已經選好的邊構成環。
我們可以採用結構體來儲存邊,結構體裡的資料變數是兩個頂點和邊的權重,將所有的邊存到乙個邊陣列裡,然後將陣列排序,從前往後邊的權重逐漸增加。如何判斷「這條邊不會與已經選好的邊構成環」條件呢,若是構成環,實際上這條邊的兩個頂點已經在選好的邊**現,因此我們可以採用並查集的思想,若是這條邊能夠選入,則將兩個頂點各自屬於的集合合併,若是不能則意味著兩個頂點隸屬於乙個集合。
(關於並查集的注意點請看之前的blog:
注意:若是邊權重為0,則代表這兩個點之間沒有邊.
要注意觀察題意,如將「黃河之水天上來」作為乙個超級原點,將消耗mp作為兩點之間邊的權值。
求最小生成樹可採用kruskal演算法。
#include
#include
#include
#include
using
namespace std;
int n;
long
long ans =0;
struct edge
edge
(const edge&t):u
(t.u),v
(t.v),w
(t.w)
bool
operator
<
(const edge& t)
const};
int par[
100000]=
;int rank[
100000]=
;int
find
(int i)
bool
unite
(int i,
int j)
else
return
true;}
edge edge[
100000];
long
long number =0;
intmain()
for(
int i =
1; i < n+
1; i++
)for
(int i =
1;i<=n;i++
)for
(int j =
1; j <= n; j++
)sort
(edge,
&edge[number]);
for(
int i =
0; i < number; i++
)printf
("%lld"
, ans)
;}
魔法東東 最小生成樹
題意 東東在老家農村無聊,想種田。農田有 n 塊,編號從 1 n。種田要灌溉,眾所周知東東是乙個魔法師,他可以消耗一定的 mp 在一塊田上施展魔法,使得黃河之水天上來。他也可以消耗一定的 mp 在兩塊田的渠上建立傳送門,使得這塊田引用那塊有水的田的水。1 n 3e2 黃河之水天上來的消耗是 wi,i...
掌握魔法 東東 I(最小生成樹kruskal)
東東在老家農村無聊,想種田。農田有 n 塊,編號從 1 n。種田要灌氵 眾所周知東東是乙個魔法師,他可以消耗一定的 mp 在一塊田上施展魔法,使得黃河之水天上來。他也可以消耗一定的 mp 在兩塊田的渠上建立傳送門,使得這塊田引用那塊有水的田的水。1 n 3e2 黃河之水天上來的消耗是 wi,i 是農...
最小生成樹問題
1.構造可以使n個城市連線的最小生成樹。問題描述 給定乙個地區的n個城市間的距離網,用prim演算法或kruskal演算法建立最小生成樹,並計算得到的最小生成樹的代價。4 要求 1 城市間的距離網採用鄰接矩陣表示,鄰接矩陣的儲存結構定義採用課本中給出的定義,若兩個城市之間不存在道路,則將相應邊的權值...