藍橋杯 ALGO 6 安慰奶牛

2021-10-02 08:33:03 字數 2579 閱讀 4355

問題描述

farmer john變得非常懶,他不想再繼續維護供奶牛之間供通行的道路。道路被用來連線n個牧場,牧場被連續地編號為1到n。每乙個牧場都是乙個奶牛的家。fj計畫除去p條道路中盡可能多的道路,但是還要保持牧場之間 的連通性。你首先要決定那些道路是需要保留的n-1條道路。第j條雙向道路連線了牧場sj和ej(1 <= sj <= n; 1 <= ej <= n; sj != ej),而且走完它需要lj的時間。沒有兩個牧場是被一條以上的道路所連線。奶牛們非常傷心,因為她們的交通系統被削減了。你需要到每乙個奶牛的住處去安慰她們。每次你到達第i個牧場的時候(即使你已經到過),你必須花去ci的時間和奶牛交談。你每個晚上都會在同乙個牧場(這是供你選擇的)過夜,直到奶牛們都從悲傷中緩過神來。在早上 起來和晚上回去睡覺的時候,你都需要和在你睡覺的牧場的奶牛交談一次。這樣你才能完成你的 交談任務。假設farmer john採納了你的建議,請計算出使所有奶牛都被安慰的最少時間。

輸入格式

第1行包含兩個整數n和p。

接下來n行,每行包含乙個整數ci。

接下來p行,每行包含三個整數sj, ej和lj。

輸出格式

輸出乙個整數, 所需要的總時間(包含和在你所在的牧場的奶牛的兩次談話時間)。

樣例輸入

5 610

1020630

1 2 5

2 3 5

2 4 12

3 4 17

2 5 15

3 5 6

樣例輸出

176(資料有誤,應該是178)

資料規模與約定

5 <= n <= 10000,n-1 <= p <= 100000,0 <= lj <= 1000,1 <= ci <= 1,000。

題意:這道題其實本身不是特別難,主要就是題意難以理解,主要是計算安慰所有的牛最短的時間,所有的牧場中的牛要安慰一次,但是題意指出起始點的牛要安慰兩次。根據題意構造一顆最小生成樹即解決總的安慰時間最短,但是樹中的節點也存在權值,所以不能按照常規的套路來做,看了網上的許多老鐵做的方法,把2*邊的權值+邊連線兩點的安慰時長作為邊的新的權值,然後在使用最小生成樹的方法。藍橋杯的官網的錦囊也說了這個方法。

思路:用結構體儲存兩點以及兩點之間新的權值,然後加入優先順序佇列中,對《進行過載後,按照權值從小到大的順序排列,然後使用克魯斯卡爾演算法解決總的時長。此演算法中使用了並查集來解決問題,對於一顆最小生成樹,只有集合,對優先順序佇列中的元素中包含的兩點依次判斷,判斷是否屬於乙個集合中,不屬於乙個集合要進行合併,此處合併對於小樹貼到大樹上的優點不明顯,和任意貼時間差不多,但是路徑壓縮還是需要的,樹一直長高會導致查詢效率變低,所以要進行路徑壓縮。

我在最後就是發現在藍橋杯的oj上不能使用system("pause");來使執行框暫停,會報錯乙個測試點都通不過。所以一定不要手殘加了!!!

**1:小樹貼到大樹上

#include #include#include#define n 10010

using namespace std;

struct node

friend bool operator < (const node &a, const node &b)

};priority_queueq;

int cost[n],s[n];

int find(int x)

}void union(int u, int v)

else }}

int kruskal()

} return sumdis;

}int main(int argc, char** ar**)

for (int i = 0; i < p; i++) ); //把路徑的兩倍+路徑上兩個節點的和作為邊的新權值

} int sumcost = kruskal();

sumcost += *min_element(cost+1,cost+n);//min_element函式主要求出的是給定陣列長度的最小值

cout << sumcost << endl;

return 0;

}

**2:第乙個點貼在第二個點上

#include #include#include#define n 10010

using namespace std;

struct node

friend bool operator < (const node &a, const node &b)

};priority_queueq;

int cost[n], mindis, s[n];

int find(int x)

}int kruskal()

} return sumdis;

}int main(int argc, char** ar**)

for (int i = 0; i < p; i++) ); //把路徑的兩倍+路徑上兩個節點的和作為邊的新權值

} int sumcost = kruskal();

sumcost += *min_element(cost+1,cost+n);

cout << sumcost << endl;

return 0;

}

藍橋杯 演算法訓練 ALGO 6 安慰奶牛

問題描述 farmer john變得非常懶,他不想再繼續維護供奶牛之間供通行的道路。道路被用來連線n個牧場,牧場被連續地編號為1到n。每乙個牧場都是乙個奶牛的家。fj計畫除去p條道路中盡可能多的道路,但是還要保持牧場之間 的連通性。你首先要決定那些道路是需要保留的n 1條道路。第j條雙向道路連線了牧...

藍橋杯 安慰奶牛

演算法訓練 安慰奶牛 時間限制 1.0s 記憶體限制 256.0mb 錦囊1使用最小生成樹演算法。錦囊2將每條邊 a,b 的權值lj改變為2lj ca cb,然後使用最小生成樹來計算。問題描述 farmer john變得非常懶,他不想再繼續維護供奶牛之間供通行的道路。道路被用來連線n個牧場,牧場被連...

藍橋杯安慰奶牛

紀念一下,這是我第一次不依靠網上的 自己寫及格的一次題。雖然仍然執行超時,但是真的已經很給我這個 小白信心了 問題描述 farmer john變得非常懶,他不想再繼續維護供奶牛之間供通行的道路。道路被用來連線n個牧場,牧場被連續地編號為1到n。每乙個牧場都是乙個奶牛的家。fj計畫除去p條道路中盡可能...