現有村落間道路的統計數據表中,列出了有可能建設成標準公路的若干條道路的成本,求使每個村落都有公路連通所需要的最低成本。
輸入格式:
輸入數據包括城鎮數目正整數NNN(≤1000\le 1000≤1000)和候選道路數目MMM(≤3N\le 3N≤3N);隨後的MMM行對應MMM條道路,每行給出3個正整數,分別是該條道路直接連通的兩個城鎮的編號以及該道路改建的預算成本。爲簡單起見,城鎮從1到NNN編號。
輸出格式:
輸出村村通需要的最低成本。如果輸入數據不足以保證暢通,則輸出−1-1−1,表示需要建設更多公路。
輸入樣例:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
輸出樣例:
12
參考代碼:
#include <stdio.h>
#include <stdlib.h>
//表示起來比較複雜,其實根據題目意思可以進行簡單表示
/*鄰接矩陣表示*/
/*最小生成樹-Prim算法實現*/
/*MST用鄰接表表示*/
#define MaxNum 1000
#define INFINITY 65533
typedef int Vertex;
typedef int Weight;
//鄰接矩陣定義
struct GNode{
int Nv;
int Ne;
Weight G[MaxNum][MaxNum];
};
typedef struct GNode *Graph;
struct ENode{
Vertex V1;
Vertex V2;
Weight EW;
};
typedef struct ENode *Edge;
//鄰接表定義
typedef struct AdjNode *PAdjNode;
struct AdjNode{
Vertex adj;//下標
Weight W;
PAdjNode next;
};
struct HNode{
PAdjNode firstNode;
};
typedef struct HNode HNODE[MaxNum];
struct LGNode{
int V;
int E;
HNODE LG;
};
typedef struct LGNode *LGraph;
struct LENode{
Vertex V1;
Vertex V2;
Weight LEW;
};
typedef struct LENode *LEdge;
Vertex FindMin(Graph G, int dist[])
{
Vertex MinV;
Weight Mindist = INFINITY;
for (int i = 1; i <= G->Nv; i++)
if (dist[i] != 0 && dist[i] < Mindist){
Mindist = dist[i];
MinV = i;
}
if (Mindist < INFINITY)
return MinV;
else
return -1;
}
Weight Prim(Graph G)
{
Weight TotalWeight = 0;
int cnt = 0;
LGraph MST = (LGraph)malloc(sizeof(struct LGNode));
Vertex S = 1;
Vertex V;
int dist[MaxNum];
Vertex path[MaxNum];
for (int i = 1; i <= G->Nv; i++){
dist[i] = G->G[S][i];
path[i] = S;
}
dist[S] = 0;
cnt++;
path[S] = -1;
while (1){
V = FindMin(G, dist);
if (V == -1)
break;
TotalWeight += dist[V];
dist[V] = 0;
cnt++;
for (int i = 1; i <= G->Nv; i++)
if (dist[i] != 0 && G->G[V][i] < INFINITY)
if (G->G[V][i] < dist[i]){
dist[i] = G->G[V][i];
path[i] = V;
}
}
if (cnt < G->Nv)
return -1;
else
return TotalWeight;
}
int main(int argc, char const *argv[])
{
Graph G = (Graph)malloc(sizeof(struct GNode));
Edge E = (Edge)malloc(sizeof(struct ENode));
int N, M;
scanf("%d %d\n", &N, &M);
G->Nv = N;
G->Ne = M;
//圖初始化
for (int i = 1; i <= G->Nv; i++)
for (int j = 1; j <= G->Nv; j++)
G->G[i][j] = INFINITY;
//插入邊
for (int i = 0; i < G->Ne; i++){
scanf("%d %d %d", &E->V1, &E->V2, &E->EW);
G->G[E->V1][E->V2] = E->EW;
G->G[E->V2][E->V1] = E->EW;
}
int cost;
cost = Prim(G);
printf("%d\n", cost);
system("pause");
return 0;
}