1. 程式人生 > >【貪心】駱駝商隊 Camel Trading

【貪心】駱駝商隊 Camel Trading

在一片古老的大地上,雖然商業已經非常繁榮,但是那裡的人們仍然延續著古老的交易方式。

他們牽著駱駝在城市之間往來奔波,販運成批的商品,換來一袋袋的金幣。 

這片大陸上有N個城市,編號為1„„N。在一些城市之間有路可通,有路就有商隊。

但是在不同的城市之間經商所得的收益不同,在下面的這個N=4的例子中,在城市1和城市2之間進行一次交易可以獲得40枚金幣,在城市2和3之間交易一次可以獲得50枚金幣,等等。


在任意兩個城市之間,這樣的交易只能進行一次。因為你第二次販運你的商品時,人們 對它們就不會感興趣了。  現在你隻身來到這個大陸上,用有限的資金在每個城市中購買了一支商隊。你需要想辦法讓你的這N支商隊給你帶來最大的經濟收益。

任務說明  給出這個大陸的地圖和每兩個城市之間的貿易值(如果這兩個城市之間有路可通的話),你需要指揮你的N支商隊進行一次經商,使得這N支商隊在這次經商中獲得的總收益最大。

注意:你的每支商隊只能進行一次交易,即它們只能從它們所在的城市到達一個相鄰的城市。當然,它們也可以不進行任何交易。  

輸入資料  

輸入檔案的第一行有兩個整數N(1  N  100)、M(M  0),分別表示這個大陸上的城市數和道路數。  接下來有M行,每行包括三個整數i、j(1  i,j  N且i  j)、v(1  V  10000),表示一條道路的資訊。其中i和j表示這條路在城市i和城市j之間,v表示沿著這條路進行一次交易所得的收益。i和j的順序是無關的,並且任意兩個城市之間最多存在一條路。    

輸出資料  

你的輸出檔案應該2行,第1行包含N個整數。其中第k個整數表示你在城市k中的商隊將要前往哪個城市進行交易(如果這支商隊進行交易的話)或者為0(如果這支商隊不進行任何交易)。第2行輸出最大收益值。  

  輸入輸出樣例


【演算法分析】  本題轉化成模型就是:在一個無向圖中,對於每個點,取一條和它相關聯的邊(如果這樣的邊存在的話),使得取出來的所有邊的權和最大。  

首先,如果這個圖是不連通的,那麼它的各個連通分量之間是沒有任何聯絡的。對這些連通分量中的問題可以分別獨立地解決,合併起來就是整個問題的解。

所以我們在下面的討論中假定圖是連通的。  

直觀地考慮,如果圖中存在度為1的點,那麼就把這一點上的唯一的一條邊分配給這個點(將某條邊“分配”給某個點的含義是:將這條邊作為和這一點相關聯的邊取出來,同時這一點就失效了,因為和它相關聯的其他邊都不能再取了)。

如果不存在這樣的點,那麼此時有兩種情況:一種是邊數等於點數,那麼這個圖就是一個環,這時可以取出圖中所有的邊;一種是邊數大於點數,那麼就可以把這個圖中權最小的一條邊直接刪去,因為這條邊“顯然”不會被取到的。 

 依據這樣一個直觀思想,本題可以用貪心法來解決。

 貪心演算法(用於連通圖): 

 1、如果圖中只有一個點,直接結束演算法。  

2、如果圖中存在度為1的點,執行3;否則轉4。 

 3、任意找一個度為1的點v,將v上的唯一一條邊分配給它。轉2。 

4、如果圖中的邊數等於點數,執行5;否則轉6。  

5、設圖中的點數(也就是邊數)為n。任取一條邊e1,將它分配給它的兩個端點中的任意

一個v1;然後將v1上的另一條邊e2分配給e2的另一個端點v2;將v2上的另一條邊e3分配給e3的另一個端點v3;„„如此重複直到將en分配給vn,即圖中所有的邊都已分配,結束演算法。 

 6、將圖中權最小的邊不分配而直接刪去。如果此時圖仍然連通,則轉2;否則對這個圖的兩個連通分量分別執行本演算法。