暂时只写了kruskal,prim算法和Dijkstra算法暑假写
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
// 1.求此图的最小代价生成树
// 2.求此图的拓扑排序
// 3.求此图的关键路径
// 用邻接矩阵建立有向图,无向图, 有向网,无向网
/*
#define maxn 30
typedef enum{ DG,DN,AG,AN }GraphKind; //有向图 有向网 无向图 无向网
typedef struct ArcCell {
VRType adj; //顶点关系类型,无权图用1或0表示是否相邻; 带权图则为权值类型
InfoType *info; //边或弧相关信息指针
} AdjMatrix[ maxn ][ maxn ];
typedef struct {
VertexType vexs[ maxn ]; //顶点向量
AdjMatrix arcs; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
GraphKind kind; //图的种类标志
} MGraph;
*/
//无向图的具体表示
#define max_vexNum 26 // 最大城市个数
#define INF 100000
int visited[max_vexNum][max_vexNum];//用来表示边visited[i][j]是否被访问过,初始化都是0
int set[max_vexNum];
typedef struct{
int vex_num, arc_num; // 顶点数 边数
char vexs[max_vexNum]; // 顶点向量
int arcs[max_vexNum][max_vexNum]; // 邻接矩阵
}Graph;
//基于无向网邻接矩阵
void CreateGraph(Graph *G) {
int i, j, w;
printf("请输入定点数和边数\n");
scanf("%d%d", &G->vex_num, &G->arc_num);
printf("输入边(vi,vj)的下标i,下标j和权w:\n");
for(i=1;i<=G->vex_num;i++)
for(j=1;j<=G->vex_num;j++) {
scanf("%d", &G->arcs[i][j]);
if(G->arcs[i][j]==0)
G->arcs[i][j]=INF;
}
}
void Kruskal(Graph *G) {
printf("最小生成树是:\n");
int k=1;
int i,j;
int a=1,b=1;
int min = G->arcs[a][b];
//初始化visited[][]
for(i=1;i<=G->vex_num;i++)
for(j=1;j<=G->vex_num;j++)
visited[i][j]=0; //表示边i-j没有被访问过
for(i=1;i<=G->vex_num;i++)
set[i]=i;
while(k <= G->vex_num-1) {//V-1次
//找出最小边i->j
for(i=1;i<=G->vex_num;i++)
for(j=1;j<=G->vex_num;j++)
if(G->arcs[i][j]<min && visited[i][j]==0) {
min=G->arcs[i][j];
a=i;
b=j;
}
visited[a][b]=1;
visited[b][a]=1;
min=INF;
if(set[a]!=0 || set[b]!=0) {
k++;
printf("%d->%d\n", a, b);
set[a]=0;
set[b]=0;
}
}
}
int main() {
Graph *G;
G = (Graph*)malloc(sizeof(Graph));
CreateGraph(G); //创建一个无向网
Kruskal(G);
return 0;
}
测试样例:
6 9
0 5 6 4 0 0
5 0 1 2 0 0
6 1 0 2 5 3
4 2 2 0 0 4
0 0 5 0 0 4
0 0 3 4 4 0
答案是:
2->3
2->4
3->6
1->4
5->6