東東在老家農村無聊,想種田。農田有 n 塊,編號從 1~n。種田要灌氵
眾所周知東東是乙個魔法師,他可以消耗一定的 mp 在一塊田上施展魔法,使得黃河之水天上來。他也可以消耗一定的 mp 在兩塊田的渠上建立傳送門,使得這塊田引用那塊有水的田的水。 (1<=n<=3e2)
黃河之水天上來的消耗是 wi,i 是農田編號 (1<=wi<=1e5)
建立傳送門的消耗是 pij,i、j 是農田編號 (1<= pij <=1e5, pij = pji, pii =0)
東東為所有的田灌氵的最小消耗
第1行:乙個數n
第2行到第n+1行:數wi
第n+2行到第2n+1行:矩陣即pij矩陣
東東最小消耗的mp值
input45
4430 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
output
9
首先依然是對題目的理解,假如沒有「天上來」的操作,那麼就是乙個簡單的最小生成樹問題,使用kruskal演算法就可以求解。
但是此題並不是那麼簡單,黃河之水可以天上來,那麼每塊田就多出了乙個來水的渠道。既然如此,可以把黃河水看成乙個新的節點,然後對所有的點使用kruskal演算法求解即可。
kruskal演算法:將所有的邊按照從小到大的順序排序,依次取出最小的邊,判斷是否可以和已選出的邊形成迴路(利用並查集),若不會則選擇該邊,並將該邊兩個端點所在集合合併。共找出n-1條邊即可。
#include
#include
#include
using
namespace std;
const
int maxn=
310;
//田個數的最大值
const
int maxm=
90000
;//邊個樹的最大值
struct edge
edges[maxm]
;int tot=0;
//邊的數目
bool
cmp(edge x,edge y)
int par[maxn]
,rnk[maxn]
;void
init
(int n)
intfind
(int x)
bool
unite
(int x,
int y)
intmain()
for(
int i=
1;i<=n;i++)}
}sort
(edges,edges+tot,cmp)
;int start=0;
//邊集種選的邊
int mp=0;
//消耗的法力值
for(
int i=
0;i) cout
}
M 昂貴的聘禮 超級源點加dij
本菜雞還是太菜了,看了半天別人的題解發現理解錯題目意思了,題目的等級是這樣規定的如果你的等級是x,最大差值k,那麼你可以交易的人的等級就在 x k,x k 之間,其他等級都不可以,然後因為你沒有等級限制,那麼就特別難搞,我們就列舉假設和我們交換的人的最低等級,但是最低等級 m要包含酋長的等級所以最低...
poj1364(注意超級源點的選擇)
題目大意 已知乙個序列a 1 a 2 a n 給出它的若干子串行以及對該子串行的 約束條件,例如a si a si 1 a si 2 a si ni 且a si a si 1 a si 2 a si ni or ki。求是否存在滿足以上m個要求的數列。是 則輸出 lamentable kingdom...
POJ 1062 昂貴的聘禮 最短路 超級源點
年輕的探險家來到了乙個印第安部落裡。在那裡他和酋長的女兒相愛了,於是便向酋長去求親。酋長要他用10000個金幣作為聘禮才答應把女兒嫁給他。探險家拿不出這麼多金幣,便請求酋長降低要求。酋長說 嗯,如果你能夠替我弄到大祭司的皮襖,我可以只要8000金幣。如果你能夠弄來他的水晶球,那麼只要5000金幣就行...