7-2 畅通工程之最低成本建设问题 (30分)
某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路相连,只要互相间接通过快速路可达即可)。现得到城镇道路统计表,表中列出了有可能建设成快速路的若干条道路的成本,求畅通工程需要的最低成本。
输入格式:
输入的第一行给出城镇数目N (1<N≤1000)和候选道路数目M≤3N;随后的M行,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号(从1编号到N)以及该道路改建的预算成本。
输出格式:
输出畅通工程需要的最低成本。如果输入数据不足以保证畅通,则输出“Impossible”。
输入样例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
输出样例1:
12
输入样例2:
5 4
1 2 1
2 3 2
3 1 3
4 5 4
输出样例2:
Impossible
代码仅供参考
Accepted Code
#include<bits/stdc++.h>
using namespace std;
#define MaxVertexNum 1005
typedef int Vertex; //顶点数据类型
typedef int WeightType; // 边的权值类型
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; // 顶点数
int Ne; // 边数
WeightType G[MaxVertexNum][MaxVertexNum]; //邻接矩阵
};
typedef PtrToGNode MGraph; //以邻接矩阵存储的图类型
struct {
Vertex vertex; //上一个父亲节点的编号
WeightType type; //长度
} Closedge[MaxVertexNum];
//标记顶点是否入树
bool Visited[MaxVertexNum];
MGraph CreatG(int, int);
bool Prim(MGraph MG);
int main() {
int N, M;
cin >> N >> M;
MGraph MG = CreatG(N, M);
Prim(MG);
return 0;
}
MGraph CreatG(int N, int M) {
MGraph MGra = new GNode;
MGra->Nv = N;
MGra->Ne = M;
//矩阵下标从0开始
int a, b, c;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
MGra->G[i][j] = INT_MAX;
}
}
for (int i = 0; i < MGra->Ne; ++i) {
cin >> a >> b >> c;
//创建无向图
if (MGra->G[a - 1][b - 1] > c) {
MGra->G[a - 1][b - 1] = c;
MGra->G[b - 1][a - 1] = c;
}
}
for (int i = 0; i < MaxVertexNum; ++i) {
Visited[i] = false;
Closedge[i].type = INT_MAX;
}
return MGra;
}
bool Prim(MGraph MG) {
int sum = 0;
//辅助数组初始化
int pos = 0;
for (int i = pos; i < MG->Nv; ++i) {
//先把第一个点放到树里
if (pos != i) {
Closedge[i].type = MG->G[pos][i];
Closedge[i].vertex = pos;
}
}
Closedge[pos].type = 0;
Visited[pos] = true;
//选择其他N-1个顶点
for (int i = 1; i < MG->Nv; ++i) {
int min = INT_MAX;
for (int j = 0; j < MG->Nv; ++j) {
if (!Visited[j] && min > Closedge[j].type) {
min = Closedge[j].type;
pos = j;
}
}
if (min == INT_MAX) {
printf("Impossible");
return false;
}
sum += min;
Closedge[pos].type = 0;
Visited[pos] = true;
//用新加入的点,更新Closedge值
for (int j = 0; j < MG->Nv; ++j) {
if (!Visited[j] && Closedge[j].type > MG->G[pos][j]) {
Closedge[j].type = MG->G[pos][j];
}
if (!Visited[j] && Closedge[j].type > MG->G[j][pos]) {
Closedge[j].type = MG->G[j][pos];
}
}
}
printf("%d", sum);
return true;
}