您的位置:首页 > 其它

08-图7 公路村村通 (30分)

2017-05-26 10:39 316 查看
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Maxn 1005
#define INF 100005
typedef struct GNode* MGraph;
struct GNode {
int Nv, Ne;
int G[Maxn][Maxn];
};

typedef struct AdjNode* AdjList;
struct AdjNode {
int V;
AdjList Next;
};

typedef struct HNode {
AdjList FirstEdge;
}List[Maxn];

typedef struct LGNode* LGraph;
struct LGNode {
int Nv;
List Head;
};

typedef struct ENode* Edge;
struct ENode {
int v1, v2;
};

void PrintGraph(MGraph MG) {
int v, w;
for(v = 1; v <= MG->Nv; v++) {
for(w = 1; w <= MG->Nv; w++)
printf("%3d", MG->G[v][w]);
printf("\n");
}
}

LGraph CreateLGraph(int n) {
int i;
LGraph MST = (LGraph)malloc(sizeof(struct LGNode));
MST->Nv = n;
for(i = 1; i <= n; i++)
MST->Head[i].FirstEdge = NULL;
return MST;
}

MGraph CreateMGraph(int n, int m) {
int v, w, v1, v2, W;
MGraph MG = (MGraph)malloc(sizeof(struct GNode));
MG->Ne = m;
MG->Nv = n;
for(v = 1; v <= n; v++)
for(w = 1; w <= n; w++)
MG->G[v][w] = INF;
for(v = 1; v <= m; v++) {
scanf("%d%d%d", &v1, &v2, &W);
MG->G[v1][v2] = MG->G[v2][v1] = W;
}
return MG;
}

void InsertEdge(LGraph MST, Edge E) {
AdjList NewNode = (AdjList)malloc(sizeof(struct AdjNode));
NewNode->V = E->v1;
NewNode->Next = MST->Head[E->v1].FirstEdge;
MST->Head[E->v1].FirstEdge = NewNode;
NewNode = (AdjList)malloc(sizeof(struct AdjNode));
NewNode->V = E->v2;
NewNode->Next = MST->Head[E->v2].FirstEdge;
MST->Head[E->v2].FirstEdge = NewNode;
}

int FindMinDist(MGraph MG, int dist[]) {
int i, Mindist, Minv;
Mindist = INF;
for(i = 1; i <= MG->Nv; i++) {
if(dist[i] != 0 && dist[i] < Mindist) {
Mindist = dist[i];
Minv = i;
}
}
if(Mindist != INF) return Minv;
else return -1;
}

void Prim(MGraph MG, LGraph MST) {
int dist[Maxn], parent[Maxn], Tweight, v, w;
int vcnt;
Edge E = (Edge)malloc(sizeof(struct ENode));
//初始化各项数值,dist的初始值,若与源点邻接则为边权,否则为无穷,先假定每个节点父节点为源点
for(v = 1; v <= MG->Nv; v++) {
dist[v] = MG->G[1][v];
parent[v] = 1;
}
Tweight = vcnt = 0;
//将源点收入MST
dist[1] = 0;
vcnt++;
parent[1] = -1;
//进行循环取节点
for( ; ; ) {
//找出为收入节点中dist最小者
v = FindMinDist(MG, dist);
if(v == -1) break;
//将v与边收入MST
E->v1 = parent[v];
E->v2 = v;
InsertEdge(MST, E);
Tweight += dist[v];
dist[v] = 0;
vcnt++;
//更新dist
for(w = 1; w <= MG->Nv; w++)
if(dist[w] != 0 && MG->G[v][w] != INF) {
if(MG->G[v][w] < dist[w]) {
dist[w] = MG->G[v][w];
parent[w] = v;
}
}
}
if(vcnt != MG->Nv) Tweight = -1;
printf("%d\n", Tweight);
}

int main() {
int N, M;
MGraph MG;
LGraph MST;
scanf("%d%d", &N, &M);
MG = CreateMGraph(N, M);//PrintGraph(MG);
MST = CreateLGraph(N);
Prim(MG, MST);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PTA