输出指定无向图的最小生成树

实验报告

实验内容

输出指定无向图的最小生成树。

实验环境

Windows10x64、VS 2019(或DevC++ 5)

算法描述

调用关系:

main
CreateMatrix
Print
Prim
Dfs
DfsCore
IsUcg

源程序清单

SimpleGrap.cpp:

#include<stdio.h>
#include<stdlib.h>
#include"Graphics.h"
void Print(_* _0){
    
    
	printf("规模:%d\n", _0->Size); {
    
    
		printf("┏");for (int x = 0; x < _0->Size; x++) printf("    ");printf("┓\n");
	}
	for (int y = 0; y < _0->Size; y++){
    
    
		printf("┃");
		for (int x = 0; x < _0->Size; x++) printf("%3d ", _0->Data[x][y]);
		printf("┃\n");
	}{
    
    
		printf("┗");for (int x = 0; x < _0->Size; x++) printf("    ");printf("┛\n");
	}
}
_ CreateMatrix(){
    
    //创建邻接矩阵
	printf("\n键入图规模:");
	N len = *IntScanner(0);
	len = len > 0 ? len : 0;
	printf("规模为%d。\n\n", len);
	printf("输入矩阵,其中\"0\"表示无路径:\n");
	_ _0 = *(_*)malloc(sizeof(_));
	_0.Size = len;
	if (len <= 0) return _0;
	Npp X = (Npp)malloc(len * sizeof(Np));
	for (int i = 0; i < len; i++)X[i] = (Np)malloc(len * sizeof(N));
	_0.Data = X;
	for (int y = 0; y < len; y++){
    
    
		for (int x = 0; x < len; x++){
    
    
			printf("当前键入一个整数作为矩阵第%d行%d列值:", y, x);
			N push = *IntScanner(0);
			printf("检测到键入的值为%d\n", push);
			if (push <= 0) push = 0;
			_0.Data[x][y] = push;
		}
	}printf("矩阵输入成功。\n");
	/*画矩阵*/Print(&_0); /*画完了*/
	return _0;
}
bool IsUcg(_* _0){
    
    
	if (_0 == NULL || _0->Size <= 0) return false;//NULL检查
	for (int n = 0; n < _0->Size; n++){
    
    //自回路检查
		if (_0->Data[n][n] != 0) return false;
	}
	for (int n = 0; n < _0->Size; n++){
    
    //无向性检查
		bool b = true;
		for (int i = 0; i < _0->Size; i++){
    
    
			if (_0->Data[n][i] != _0->Data[i][n]) return false;//权值不等
			if (_0->Data[n][i] != 0) b = false;//连通
		}if (b) return false;
	}return true;
}
bool DfsCore(_* _0, int Now, bool* vstd) {
    
    
	vstd[Now] = true;//这个顶点已经被访问过了
	bool b = true;
	//printf("%d ", Now);
	int c = 0;
	for (int i = 0; i < _0->Size; i++){
    
    
		if (_0->Data[Now][i] != 0) {
    
    
			if (!vstd[i]) {
    
     b = b && DfsCore(_0, i, vstd);
			}else{
    
     c++;
				if (c > 1) b = false;
			}
		}
	}return b;
}
bool Dfs(_* _0, int Now){
    
    
	if (_0 == NULL || _0->Size <= 0 || _0->Data == NULL){
    
    //是无向连通简单图
		//printf("非无向连通简单图。\n\n");
		return false;
	}
	bool* np = (bool*)malloc(_0->Size * sizeof(bool));
	for (int i = 0; i < _0->Size; i++)np[i] = 0;
	bool b = true;
	b = DfsCore(_0, Now, np);
	return b;
}
_ Prim(_ grap)
{
    
    
	_ _0 = *(_*)malloc(sizeof(_));
	_0.Size = grap.Size;
	if (_0.Size > 0){
    
     //无向图是对称的,所以出度入度值不去区分
		Npp X = (Npp)malloc(grap.Size * sizeof(Np));
		for (int i = 0; i < grap.Size; i++)X[i] = (Np)malloc(grap.Size * sizeof(N));
		_0.Data = X;
		for (int y = 0; y < grap.Size; y++)//赋初值
			for (int x = 0; x < grap.Size; x++)_0.Data[x][y] = 0;
		int count = 0;
		if (IsUcg(&grap)) {
    
    //是无向连通简单图
			int* vstd = (int*)malloc(sizeof(int) * grap.Size);
			int vstdTop = 0;
			vstd[vstdTop++] = 0;
			for (int maxlooptimes=0;maxlooptimes<32767;maxlooptimes++)/*死循环,但不完全死*/{
    
    
				int min = 32767;
				int start=0; int end=0;//权最小的路径为<start,end>
				for (int tin = 0; tin < vstdTop; tin++){
    
    
					for (int nowi = 0; nowi < grap.Size; nowi++){
    
    //选择权最小的路径
					   if (min>=grap.Data[vstd[tin]][nowi]&&grap.Data[vstd[tin]][nowi]>0) {
    
    
							min = grap.Data[vstd[tin]][nowi];
							end = nowi;
							start = vstd[tin];
						}
					}
				}
		grap.Data[start][end]=0;grap.Data[end][start]=0; //无论是不是树,访问过的路径就要删
				if (min >= 32767) min = 0;
				_0.Data[start][end] = min; _0.Data[end][start] = min; //预添加路径
				if (Dfs(&_0, start)) {
    
    //是否为树
					vstd[vstdTop++] = end; count++;
				}else{
    
    
					_0.Data[start][end] = 0; _0.Data[end][start] = 0; //撤销预添加
				}if (IsUcg(&_0)&&count>=_0.Size) break;//添加了所有顶点,跳出
			}
		}
	}return _0;
}

Head.h:

#pragma once
typedef int N;
typedef int* Np;
typedef int** Npp;
struct _{
    
    
	Npp Data;
	N Size;
};
Np IntScanner(N);
_ CreateMatrix(); 
_ Prim(_);
void Print(_*);
bool Dfs(_*, int);

Main.cpp:

#include<stdio.h>
#include<stdlib.h>
#include"Graphics.h"
int main(){
    
    
	_ l = CreateMatrix();
	_ l1 = Prim(l);
	printf("最小生成树:\n");
	Print(&l1);
	system("pause");return 0;
}

运行结果

运行结果

猜你喜欢

转载自blog.csdn.net/dscn15848078969/article/details/108763661