叢林中的路
熱帶島嶼lagrishan的首領現在面臨乙個問題:幾年前,一批外援資金被用於維護村落之間的道路,但日益繁茂的叢林無情的侵蝕著村民的道路,導致道路維修開銷巨大,長老會不得不放棄部分道路的維護。已經知道了每條路每個月的維修費用(單位為aacms)。現在長老會需要提出一種方案,即需要保證村落之間都可以互相到達,又要將每個月的道路維修費用控制在最小。村子編號為從a到i。上圖右側顯示的方案最小維修開銷為216 aacms每月。
輸入包含1~50個資料集,最後一行為0.每個資料集第一行為村落數目n, 1 < n < 27,依次用字母表的前n個字母標記。接下來有n-1行,每行的第乙個資料便是按字母順序排列的村子編號(不包括最後乙個村莊)。每個村莊後面的資料k代表該村莊通往編號在其之後的村莊的道路數目,如a 2 b 12 i 25,代表a村莊有2個編號在a之後的村莊和其相連。若k大於0,k後面會依次給出這k個村莊的編號以及各自到起始村莊的道路維修費用,如a 2 b 12 i 25,代表a和b之間道路維修費用為12, a和i之間道路維修費用為25(維修費用為不超過100的正整數).路的總數目不超過75條,每個村莊到其他村莊不會有超過15條路(包括編號在其之前和之後的)。
每個資料集有乙個輸出:針對解決方案每個月維修道路的小費用。
9
a 2 b 12 i 25
b 3 c 10 h 40 i 8
c 2 d 18 g 55
d 1 e 44
e 2 f 60 g 38
f 0g 1 h 35
h 1 i 35
3a 2 b 10 c 40
b 1 c 20
0
216
30
這題要用到的演算法是最小生成樹。其實最小生成樹有兩種常用的演算法:
prim
和kruskal
演算法。在這裡我們只介紹kruskal演算法。
演算法大致思路如下:
•對於圖g,每次尋找一條邊,此邊滿足
•1) 邊的兩個端點不同在mst中
•2) 此邊的權值在所有「邊的兩個端點不同在mst中」的邊裡為最小值
•3) 將這條邊加入mst中。
(mst為乙個集合)
那麼顯然這種演算法必須用到並查集。
讀題,題目意思就是要求我們在圖中建立乙個最小生成樹,求這個最小生成樹每條邊的權值之和。所以我們首先把每條邊讀進來(讀入可能有點麻煩,這裡因為每個村莊名字都是按字母序排列的,所以點a可以看成點0,點b可以看成點2,以此類推),接著按照權值大小進行一次從小到大的排序。然後我們從小到**擇最小生成樹的邊,只要起點和終點不在乙個集合內我們就選擇這條邊並將起點和終點所在的集合放到同乙個集合內。這樣順次做下來就是最小生成樹了。
ac**:
#include
#include
#include
#include
using
namespace std;
struct
tree
t[1005
];int n,m,f[
1005
],k,k0;
char s0,nm;
bool
cmp(
tree
x,tree
y)int
find
(int x)
void
unin
(int x,
int y)
void
work
()for
(int i=
0;i;i++)
scanf("
\n");}
sort
(t+1
,t+1
+k,cmp);
int fx,fy;
for(
int i=
1;i<=k;i++)
}printf
("%d\n"
,ans);
}int
main
()return0;
}
並查集(最小生成樹)
時間限制 1000 ms 記憶體限制 65536 kb 題目描述 有一張城市地圖,圖中的頂點為城市,無向邊代表兩個城市間的連通關係,邊上的權為在這兩個城市之間修建高速公路的造價,研究後發現,這個地圖有乙個特點,即任一對城市都是連通的。現在的問題是,要修建若干高速公路把所有城市聯絡起來,問如何設計可使...
練習 並查集 最小生成樹練習題
嗯。都是些 最最最基礎的水題 直接模板就ok了。剛學的可以一做 1.洛谷 並查集模板 include include include include include include define n 10005 define m 200005 using namespace std int n,m,...
並查集 最小生成樹(prim kruskal)
並查集,從名字上來看可以知道,是乙個集合,而且這個集合可以合併和查詢。查詢,主要是查詢集合中的某乙個元素的祖先是誰,某一些元素是不是擁有相同的祖先。合併,是把兩個不想交的集合合併為乙個集合。並查集的思想就是朋友的朋友就是朋友 雖然現實生活中並不是這樣 並查集的第一步初始化,自己是自己的祖先。乙個人來...