南陽OJ-38 佈線問題(最小生成樹應用_prim)

佈線問題

時間限制: 1000 ms  |  內存限制:65535 KB
難度: 4
 
描述
南陽理工學院要進行用電線路改造,如今校長要求設計師設計出一種佈線方式,該佈線方式須要知足如下條件:
一、把全部的樓都供上電。
二、所用電線花費最少
 
輸入
第一行是一個整數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開始),因爲安全問題,只能選擇一個樓鏈接到外界供電設備。
數據保證至少存在一種方案知足要求。
輸出
每組測試數據輸出一個正整數,表示鋪設知足校長要求的線路的最小花費。
樣例輸入
1
4 6
1 2 10
2 3 10
3 1 10
1 4 1
2 4 1
3 4 1
1 3 5 6
樣例輸出
4
最小生成樹有1.prim 2.kruskal兩種算法
下面是prim算法
#include<iostream>
using namespace std;
#define MaxSize 505
typedef struct {
    int arc[MaxSize][MaxSize];    // 鄰接矩陣
    int numV, numE;                //圖中的定點數和邊數 
}MGraph;
int main() {
    int t;
    cin >> t;
    while (t--) {
        MGraph G;
        int x, y, a, b, cost = 0;
        cin >> G.numV >> G.numE;
        for (int i = 1; i <= G.numV; i++) {            //初始化鄰接矩陣 
            for (int  j = 1; j <= G.numV; j++) {
                if (i == j) G.arc[i][j] = 0;
                else G.arc[i][j] = 200;                //題中條件 c<=100,這裏設置的數值比 100大就能夠 
            }
        }
        for (int i = 0; i < G.numE; i++) {
            cin >> x >> y;
            cin >> G.arc[x][y];
            G.arc[y][x] = G.arc[x][y];
        }
        cin >> a;                                    //找出代價最小的鏈接點 
        for (int i = 1; i < G.numV; i++) {
            cin >> b;
            if (b < a) a = b;
        }
        int adjvex[MaxSize];    //保存相關頂點下標 
        int lowcost[MaxSize];    //保存相關頂點間的邊的權值 
        adjvex[1] = 1;            //初始化第1號樓的下標爲1 
        lowcost[1] = 0;            //初始化第一個權值爲0,即1號樓加入生成樹,lowcost的值0即表示此下標的的樓號已加入生成樹 
        for (int i = 2; i <= G.numV; i++) {    //循環除了下標爲1的所有樓號 
            lowcost[i] = G.arc[1][i];        //將與1號樓鏈接的樓號的權值存入數組 
            adjvex[i] = 1;                    //表示全部樓與1號樓相連 
        }
        for (int i = 1; i < G.numV; i++) {
            int min = 200;        // c <= 100 
            int j = 1, k = 0;
            while (j <= G.numV) {    //尋找與當前樓相連的權值最小的樓號 
                if (lowcost[j] != 0 && min > lowcost[j]) {
                    min = lowcost[j];
                    k = j;
                }
                j++;
            }
            //cout << adjvex[k] << k << lowcost[k] << endl;
            cost += lowcost[k];
            lowcost[k] = 0;            //lowcost的值0即表示此下標的的樓號已加入生成樹  
            for (int l = 2; l <= G.numV; l++) {        //更新加入k號樓所致使的lowcost,adjvex的變化 
                if (lowcost[l] != 0 && G.arc[k][l] < lowcost[l]) {
                    lowcost[l] = G.arc[k][l];
                    adjvex[l] = k; 
                }
            }
        }
        cout << cost+a << endl;
    }
}
相關文章
相關標籤/搜索