#include <iostream>
#include <vector>
#include <queue>
#define MaxSize 10
#define eletype int
using namespace std;
bool visited[MaxSize][MaxSize]; //全局数组,记录结点是否已补访问
typedef struct edgenode { //边表结点
int adjvex; //邻接点
int weight; //权值
edgenode *next; //下一条边
};
typedef struct vertexnode { //顶点结点
eletype data; //结点数据
edgenode *fist; //指向第一条边
}AdjList[MaxSize];
typedef struct AdjListGraph {
AdjList adjlist; //邻接表
int vex; //顶点数
int edge; //边数
};
typedef struct CSNode {
int begin; //起点
int end; //终点
int weight; //权值
};
void Init() { //初始化为未访问
for (int i = 0; i < MaxSize; i++) {
for (int j = 0; j < MaxSize; j++) {
visited[i][j] = false;
}
}
}
int Location(AdjListGraph &G, eletype c) { //寻找顶点数据的邻接点
for (int i = 0; i < G.vex; i++) {
if (G.adjlist[i].data == c) {
return i;
}
}
return -1;
}
void Create(AdjListGraph &G) { //创建图
cout << "请输入该图的顶点数以及边数:" << endl;
cin >> G.vex >> G.edge;
cout << "请输入相关顶点:" << endl;
for (int i = 0; i < G.vex; i++) {
cin >> G.adjlist[i].data;
G.adjlist[i].fist = NULL;
}
eletype a, b;
int c;
int m, n;
cout << "请输入相关边的顶点以及权值:" << endl;
for (int i = 0; i < G.edge; i++) {
cin >> a >> b>>c;
m = Location(G, a); //寻找顶点号
n = Location(G, b);
if (m != -1 && n != -1) { //寻找到位置
edgenode *temp = new edgenode;
temp->adjvex = n;
temp->weight = c;
temp->next = G.adjlist[m].fist;
G.adjlist[m].fist = temp;
}
}
}
//快速排序部分
void swap(CSNode * a, CSNode * b) {
CSNode tmp = *a;
*a = *b;
*b = tmp;
}
int partition(vector<CSNode> &array_list, int left, int right) {
int index = left;
int pivot = array_list[right].weight;
for (int i = left; i< right; i++) {
if (array_list[i].weight < pivot) {
swap(&array_list[index], &array_list[i]);
index++;
}
}
swap(&array_list[right], &array_list[index]);
return index;
}
void quick_sort(vector<CSNode> &array_list, int left, int right) {
if (left >= right){
return;
}
int index = partition(array_list, left, right);
quick_sort(array_list, left, index - 1);
quick_sort(array_list, index + 1, right);
}
int NotEmpty(vector<int> *vect) { //寻找第一个空的序号
for (int i = 0; i < MaxSize; i++) {
if (vect[i].size() == 0) {
return i;
}
}
return -1;
}
int Where_Locate(vector<int> *vect, int v) { //判断该序号在vect中的位置
for (int i = 0; i < MaxSize; i++) {
vector<int>::iterator iter;
for (iter = vect[i].begin(); iter != vect[i].end(); iter++) {
if (*iter == v) {
return i;
}
}
}
return -1;
}
int Number_of_Statistical(vector<int> *vect,int &P) { //统计顶点个数
int sum = 0;
P=0;
for (int i = 0; i < MaxSize; i++) {
sum += vect[i].size();
if (vect[i].size() != 0) {
P++;
}
}
return sum;
}
void Copy(vector<int> *vect, vector<int> *vect_temp) { //复制
for (int j = 0; j < MaxSize; j++) {
vect_temp[j].assign(vect[j].begin(), vect[j].end());
}
}
void Kruskal(AdjListGraph &G) {
vector<CSNode> vec;
for (int i = 0; i < G.vex; i++) {
edgenode *temp = G.adjlist[i].fist;
if (temp != NULL) {
if (visited[i][temp->adjvex] == false) {
CSNode p;
p.begin = i; p.end = temp->adjvex;
p.weight = temp->weight;
vec.push_back(p);
visited[i][temp->adjvex] = true;
visited[temp->adjvex][i] = true;
}
while (temp->next != NULL) {
temp = temp->next;
if (visited[i][temp->adjvex] == false) {
CSNode p;
p.begin = i; p.end = temp->adjvex;
p.weight = temp->weight;
vec.push_back(p);
visited[i][temp->adjvex] = true;
visited[temp->adjvex][i] = true;
}
}
}
} //将边信息存储在vec中
quick_sort(vec,0,vec.size()-1); //将边信息进行排序
vector<int> vect[MaxSize]; //存储连通分量部分
vector<int> vect_temp[MaxSize]; //保存修改之前的
int P = 0,M=0,E=0; //表示连通分量的个数
for (int i = 0; i < vec.size(); i++) {
Copy(vect, vect_temp);
int first = Where_Locate(vect, vec[i].begin);
int second= Where_Locate(vect, vec[i].end);
//cout << first << " " << second << endl;
if (first == -1 && second == -1) { //均不存在
int location = NotEmpty(vect);
vect[location].push_back(vec[i].begin); //存储进vect[location]
vect[location].push_back(vec[i].end);
}
else {
if (first == -1 && second != -1) { //起点不存在,终点存在
vect[second].push_back(vec[i].end);
}
else {
if (first != -1 && second == -1) { //起点存在,终点不存在
vect[first].push_back(vec[i].begin);
}
else {
if (first != -1 && second != -1) { //起点存在,终点存在
if (first != second) { //位于不同的连通分量中
int min = first > second ? second : first;
int max = first < second ? second : first;
vect[min].insert(vect[min].end(), vect[max].begin(), vect[max].end());//将vect[max]压入
vect[max].clear(); //清空
}
}
}
}
}
M = Number_of_Statistical(vect,P);
E = E + 1;
//cout << E << " " << P << " " << M << endl;
if (E + P > M) { //存在环
Copy(vect_temp, vect); //恢复原状
E = E - 1;
}
else {
cout << G.adjlist[vec[i].begin].data << " " << G.adjlist[vec[i].end].data << endl;
//输出选边
}
}
}
int main() {
AdjListGraph G;
Init();
Create(G); //创建图
Kruskal(G);
system("pause");
return 0;
}
/*
6 20
1 2 3 4 5 6
1 2 6
1 4 5
1 3 1
2 3 5
3 4 5
2 5 3
5 6 6
4 6 2
3 6 4
3 5 6
2 1 6
4 1 5
3 1 1
3 2 5
4 3 5
5 2 3
6 5 6
6 4 2
6 3 4
5 3 6
*/
图的Kruskal算法
最新推荐文章于 2024-06-15 09:15:00 发布