標籤:
布線問題時間限制:1000 ms | 記憶體限制:65535 KB難度:4
-
描述
-
南陽理工學院要進行用電線路改造,現在校長要求設計師設計出一種布線方式,該布線方式需要滿足以下條件:
1、把所有的樓都供上電。
2、所用電線花費最少
-
輸入
-
第一行是一個整數n表示有n組測試資料。(n<5)
每組測試資料的第一行是兩個整數v,e.
v表示學校裡樓的總個數(v<=500)
隨後的e行裡,每行有三個整數a,b,c表示a與b之間如果建鋪設線路花費為c(c<=100)。(哪兩棟樓間如果沒有指明花費,則表示這兩棟樓直接連通需要費用太大或者不可能連通)
隨後的1行裡,有v個整數,其中第i個數表示從第i號樓接線到外界供電設施所需要的費用。( 0<e<v*(v-1)/2 )
(樓的編號從1開始),由於安全問題,只能選擇一個樓串連到外界供電裝置。
資料保證至少存在一種方案滿足要求。
-
輸出
-
每組測試資料輸出一個正整數,表示鋪設滿足校長要求的線路的最小花費。
-
範例輸入
-
14 61 2 102 3 103 1 101 4 12 4 13 4 11 3 5 6
-
範例輸出
-
4
-
來源
-
[張雲聰]原創
-
上傳者
-
張雲聰
最小產生樹模板題,最終答案就是最小產生樹的各邊之和加上其中一個樓串連外界供電裝置所需要的花費。記錄邊時只記錄串連兩個樓的最小邊。模板套用 prim 演算法。
#include<stdio.h>#include<string.h>#define MAX_N 505#define INF 0x3f3f3f3f#include<algorithm>using namespace std;int cost[MAX_N][MAX_N]; //表示邊的權值(不存在的情況設為INF) int mincost[MAX_N]; //從集合X出發得邊到每個頂點的最小權值 bool used[MAX_N]; //頂點i是否包含在集合X(最小產生樹)中 int v; //頂點數目 int prim() //prim演算法模板 {for(int i = 1;i <= v;i++) //初始化 {mincost[i] = INF;used[i] = false;}mincost[1] = 0;int res = 0;while(true){int e = -1; // 從不屬於X的頂點中選取從X到其權值最小的頂點 for(int i = 1;i <= v;i++){if(used[i] == false && (e == -1 || mincost[i] < mincost[e]))e = i;}if(e == -1) break;used[e] = true;res += mincost[e];for(int i = 1;i <= v;i++){mincost[i] = min(mincost[i],cost[e][i]);}}return res;}int main(){int n;scanf("%d",&n);while(n--){memset(cost,INF,sizeof(cost));int e;scanf("%d%d",&v,&e);int a,b,c;for(int i = 1;i <= e;i++){scanf("%d%d%d",&a,&b,&c);cost[a][b] = cost[b][a] = min(cost[a][b],c);//只記錄串連兩個樓的最小花費 }int minn = INF,x; //找到串連外界供電裝置最小的花費 for(int i = 1;i <= v;i++){scanf("%d",&x);minn = min(minn,x); } printf("%d\n",minn + prim());//最終答案即串連v個樓的最小花費與minn之和 }return 0;}
NYOJ 38 布線問題