最小生成木問題:n都市間に通信ネットワークを構築するには,n−1回線を架設するだけでよい(隣の学校の同級生の授業)

36331 ワード

問題8最小生成木問題(難易度係数:1.1)[問題記述]n都市間に通信ネットワークを構築するには,n−1回線を架設するだけでよい.どのように最低の経済的代価でこの通信網を建設するかは、網の最小生成ツリーの問題である.[基本要求](1)クルーズカールアルゴリズムを用いてネットワークの最小生成ツリーを求める.(2)実装してセットを調べる.これにより、構築ツリー中の連通成分を表します.(3)生成ツリー内の各エッジおよびそれらの重み値をテキスト形式で出力する.[テストデータ]本題セットの練習問題を参照してください.[実装ヒント]通信回線が確立されると、必然的に双方向になる.したがって,最小生成ツリーを構築する網は必ず無方向網である.図の頂点数が30個を超えないように設定し、簡単にするために網中辺の重み値を100未満の整数に設定し、C言語で提供される乱数関数で生成することができる.図の記憶構造の選択は、操作に適応しなければならない.重み値が最も小さいエッジの選択を容易にするために,この問題の記憶構造は隣接行列の配列表現法も隣接テーブルも選択せず,記憶エッジ(重み付き)の配列で図を表す.[コンテンツを選択]スタックソートにより、選択権値が最も小さいエッジを実現します.
#pragma once
#ifndef EDGE
#define EDGE
//        
#define MaxNum 30//     
#define MaxInt 32767//   
#define MinInt -1//    
typedef char  VerType;//    
typedef int ArcType;//    
//      
typedef struct {
	VerType ver[MaxNum];//   
	ArcType arc[MaxNum][MaxNum];//    
	int vernum, arcnum;	//  ,  
}AMGraph;
//      1,Edge:      ,           
struct edge {
	VerType Head;//    
	VerType Tail;//    
	ArcType lowCost;//    
}Edge[MaxNum+1];//    
// n           n(n-1)  ,   n  ,         31, 1-30   
//  
int Locate(AMGraph G, VerType v1) {
	for (int i = 0; i < G.vernum; i++) {
		if (G.ver[i] == v1) {
			return i;
		}
	}
	return -1;
}
#endif
#pragma once
#ifndef HEAPSORT
#define HEAPSORT
#include
#include
#include"Edge.h"
//   -》   
using namespace std;
void show_heapSort_result(edge l[], int n) {
	for (int i = 1; i <=n; i++) {
		cout << l[i].lowCost << " ";
	}
	cout << endl;
}
// Heap Sort       ,r[n]               ,               ,            
//   :1、Ki>=k(2i) &&Ki>=k(2i+1) 2、ki<=k(2i) &&Ki<=k(2i+1)
//1、      
//  :1.r[2s] r[2s+1]         ,  r[2s+1] ,   r[s] r[2s]    
void heapAdjust(edge L[],int s,int m) {
	//  r[s+1,..m]  , r[s,..m]    r[s]      
	edge rc = L[s];
	for (int j = 2 * s; j <= m; j *= 2) {// N/2、N/2-1……  ,                 
		if (j < m && L[j].lowCost < L[j + 1].lowCost ) ++j;//  .r[2s] r[2s+1]
		if (rc.lowCost >= L[j].lowCost) {
			break;
		}//    ,    
		else
			L[s] = L[j]; 
			s = j;//  r[2s] r[2s+1]   
	}
	L[s] = rc;
}
//2.  ,  r[s]
//			      ,    
//2.    ,         4n
//          n/2(    )       ,   
//        ,    
void CreateHeap(edge L[],int length) {
	//      
	for (int i = length / 2; i > 0; --i) {
		heapAdjust(L,i ,length );
	}
}
//    
//            ,(n-1)   
void HeapSort(edge L[], int length) {
	CreateHeap(L, length);
	//int time = 1;
	for (int i = length; i > 1; --i) {
		edge x = L[1];
		L[1] = L[i]; 
		L[i] = x;
		heapAdjust(L, 1, i - 1);
		//printf(" %2d   \t", time++);
		//show_heapSort_result(L, length);
	}
}
//    
/*
     :    O(nlog2n)
     o(1)
  :   ;      ;        ,      ,   
*/
#endif


#include
#include"heapSort.h"
#include
using namespace std;
//     
/*
        ,      。
  ,               。
         30 ,      ,          100   ,   C            。
*/
bool createUDN(AMGraph &G) {
	cout << "Please input the vernum and arcnum(     )" << endl;//     
	cin >> G.vernum >> G.arcnum;
	cout << "Please input the name of "<<G.vernum<<" points" << endl;
	int i = 0, j = 0;
	for (i = 0; i < G.vernum; i++)
		cin >> G.ver[i];
	//       
	for (i = 0; i < G.vernum; i++) {
		for (j = 0; j < G.vernum; j++) {
			if (i != j)
				G.arc[i][j] = MaxInt;
			else 
				G.arc[i][j] = 0;
		}
	}
	//    ,     
	cout << "Please input the name of two arcnums and end with line feeds at a time,without inputing a random value as their distance"<< endl;
	VerType v1, v2;
	ArcType w;
	int p, q;
	srand((unsigned)time(NULL));
	for (i = 1; i <= G.arcnum; i++) {//       ,     
		cin >> v1 >> v2; //>> w;
		w = rand() % 100+1;// 1-100
		p = Locate(G, v1);
		q = Locate(G, v2);
		Edge[i] = { v1,v2,w };
		G.arc[p][q] = w;
		G.arc[q][p] = G.arc[p][q];
	}
	return true;
}
void show_Graph(AMGraph G) {
	int i, j;
	for (i = 0; i < G.vernum; i++) {
		for (j = 0; j < G.vernum; j++) {
			if (G.arc[i][j] == MaxInt)  printf("INF\t");
			else printf("%-3d\t", G.arc[i][j]);
		}
		cout << endl;
	}
}
//    :   
//			1.   Edge         
//			2.        ,      :
//				2.1       Edge        (u,u2);
//				2.2 Vexset     v1,v2       vs1,vs2,    
//					  vs1==vs2,  2            ,    ,            
//					vs1!=vs2,  2             ,    ,        
//      2,Vexset[i]              ,               
//    
void MiniSpanTree_Kruskal(AMGraph G) {
	//            ,  G      ,  T   
	//   
	int Vexset[MaxNum];//     
	HeapSort(Edge, G.arcnum);//Edge 1-length
	int i = 0;
	for (i = 0; i < G.arcnum; i++)
		Vexset[i] = i;
	int v1, v2;//  
	int vs1, vs2;//    
	//  
	ofstream outf;
	outf.open("C:\\Users\\Lenovo\\Desktop\\EdegeGraph.txt", ios::out);
	if (!outf) {
		cerr << "File couldn't be open" << endl;
		abort();
	}
	for (i = 1; i <= G.arcnum; i++) {
		v1 = Locate(G, Edge[i].Head);//Head  
		v2 = Locate(G, Edge[i].Tail);//Tail  
		vs1 = Vexset[v1];
		vs2 = Vexset[v2];
		if (vs1 != vs2) {
			cout << "start at point " << Edge[i].Head << " ,end at point " << Edge[i].Tail <<" value=" << Edge[i].lowCost << "
"
;// outf << "start at point " << Edge[i].Head << " ,end at point " << Edge[i].Tail<<" value="<<Edge[i].lowCost<< "
"
;// // for (int j = 0; j < G.vernum; j++) {// vs1 vs2 , vs1, if (Vexset[j] == vs2) Vexset[j] = vs1;// vs2 vs1 } } // vs1==vs2, 2 , , , } outf.close(); } int main() { AMGraph G; createUDN(G); show_Graph(G); MiniSpanTree_Kruskal(G); } /* : 7 9 a b c d e f g a b a f b c b g f e e g e d c d d g */