CCF201412 4 最優灌溉(100分)

2021-07-26 15:28:40 字數 3338 閱讀 1414

試題編號:

201412-4

試題名稱:

最優灌溉

時間限制:

1.0s

記憶體限制:

256.0mb

問題描述:

問題描述

雷雷承包了很多片麥田,為了灌溉這些麥田,雷雷在第乙個麥田挖了一口很深的水井,所有的麥田都從這口井來引水灌溉。

為了灌溉,雷雷需要建立一些水渠,以連線水井和麥田,雷雷也可以利用部分麥田作為「中轉站」,利用水渠連線不同的麥田,這樣只要一片麥田能被灌溉,則與其連線的麥田也能被灌溉。

現在雷雷知道哪些麥田之間可以建設水渠和建設每個水渠所需要的費用(注意不是所有麥田之間都可以建立水渠)。請問灌溉所有麥田最少需要多少費用來修建水渠。

輸入格式

輸入的第一行包含兩個正整數n, m,分別表示麥田的片數和雷雷可以建立的水渠的數量。麥田使用1, 2, 3, ……依次標號。

接下來m行,每行包含三個整數a

i, b

i, c

i,表示第a

i片麥田與第b

i片麥田之間可以建立一條水渠,所需要的費用為c

i。輸出格式

輸出一行,包含乙個整數,表示灌溉所有麥田所需要的最小費用。

樣例輸入

4 4

1 2 1

2 3 4

2 4 2

3 4 3

樣例輸出

6

樣例說明

建立以下三條水渠:麥田1與麥田2、麥田2與麥田4、麥田4與麥田3。

評測用例規模與約定

前20%的評測用例滿足:n≤5。

前40%的評測用例滿足:n≤20。

前60%的評測用例滿足:n≤100。

所有評測用例都滿足:1≤n≤1000,1≤m≤100,000,1≤c

i≤10,000。

ccf201412試題。

問題描述:(參見上文)。

問題分析:這是乙個最小生成樹的為問題,解決的演算法有kruskal(克魯斯卡爾)演算法和prim(普里姆) 演算法。

程式說明

方法一:

用prim演算法實現,也許是演算法複雜度的問題,,時間上超時了,只得了80分。希望有人能夠幫助改進一下。

有關最小生成樹的問題也許使用克魯斯卡爾演算法,實現上更具有優勢,只需要對所有的邊進行排序後處理一遍即可。

方法二:

用kruskal

演算法實現。有關最小生成樹的問題,使用克魯斯卡爾演算法更具有優勢,只需要對所有的邊進行排序後處理一遍即可。程式中使用了並查集,用來判定加入一條邊後會不會產生迴圈。n個結點的圖,其最小生成樹應該是n-1條邊,這個作為程式處理的結束條件。這個程式實現kruskal演算法部分的邏輯和**都是否簡潔易懂。程式中,圖採用邊列表的方式儲存,按邊的權從小到大順序放在優先佇列中,省去了排序。

參考鏈結:prim演算法

的c語言程式

。提交後得100分的c++語言程式(方法二)如下:

/* ccf201412-4 最優灌溉 */

#include #include #include using namespace std;

// 並查集類

class uf

int find(int x)

}bool union(int x, int y)

}};struct edge

};int main()

// kruskal演算法

uf uf(n);

int ans=0, count=0;

for(;;)

}// 輸出結果

cout << ans << endl;

return 0;}/*

測試資料與結果兩組:

6 10

1 2 3

1 3 1

1 4 6

2 3 5

2 5 3

3 4 5

3 5 6

3 6 4

4 6 2

5 6 6

134 4

1 2 1

2 3 4

2 4 2

3 4 3

6*/

提交後得80分的c++語言程式(方法一)如下:

/* ccf201412-4 最優灌溉 */

#include #include #include using namespace std;

int main()

// prim演算法

unsigned int min;

int next = 1, u, v;

visited[1]=1;

while(next < n)

if(visited[u]==0 || visited[v]==0)

cost[u][v] = cost[v][u] = int_max;

}// 輸出結果

cout << ans << endl;

return 0;

}

另外乙個提交後得80分的c++程式:

/* ccf201412-4 最優灌溉 */

#include #include #include using namespace std;

const int true = 1;

const int false = 0;

const int n = 1000;

unsigned int cost[n+1][n+1];

int s_set[n+1], s_count;

int vs_set[n+1], vs_count;

int n, m, ans = 0;

// prim演算法

void prim(int n)

}s_set[pj] = true;

s_count++;

vs_set[pj] = false;

vs_count--;

ans += minval;

}}int main()

// prim演算法

s_set[1] = true;

s_count = 1;

vs_set[1] = false;

vs_count = n - 1;

prim(n);

// 輸出結果

cout << ans << endl;

return 0;

}

CCF 201412 4 最優灌溉

問題描述 雷雷承包了很多片麥田,為了灌溉這些麥田,雷雷在第乙個麥田挖了一口很深的水井,所有的麥田都從這口井來引水灌溉。為了灌溉,雷雷需要建立一些水渠,以連線水井和麥田,雷雷也可以利用部分麥田作為 中轉站 利用水渠連線不同的麥田,這樣只要一片麥田能被灌溉,則與其連線的麥田也能被灌溉。現在雷雷知道哪些麥...

CCF 201412 4 最優灌溉

問題描述 雷雷承包了很多片麥田,為了灌溉這些麥田,雷雷在第乙個麥田挖了一口很深的水井,所有的麥田都從這口井來引水灌溉。為了灌溉,雷雷需要建立一些水渠,以連線水井和麥田,雷雷也可以利用部分麥田作為 中轉站 利用水渠連線不同的麥田,這樣只要一片麥田能被灌溉,則與其連線的麥田也能被灌溉。現在雷雷知道哪些麥...

CCF 201412 4 最優灌溉

試題編號 201412 4 試題名稱 最優灌溉 時間限制 1.0s 記憶體限制 256.0mb 問題描述 問題描述 雷雷承包了很多片麥田,為了灌溉這些麥田,雷雷在第乙個麥田挖了一口很深的水井,所有的麥田都從這口井來引水灌溉。為了灌溉,雷雷需要建立一些水渠,以連線水井和麥田,雷雷也可以利用部分麥田作為...