SharedSchoolSpace/作业/数据结构-金健/C++/第六章作业/第六章作业2.cpp

161 lines
7.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by 423A35C7 on 2023-12-02.
//
#include <iostream>
#include "graph.hpp"
// 这次执行一轮后不一定结束了,
void one_turn(ComplexGraph* graph) {
for (int start = 0; start < graph->node_num; ++start) {
int target;
while (true) {
int* target_ptr = std::min_element(graph->adjacency[start],
graph->adjacency[start] + graph->node_num);
// 如果最小的目标城市距离都是INT_MAX则说明start与所有城市都已连通则不再修建
if (*target_ptr == INT_MAX) {
return;
}
target = target_ptr - graph->adjacency[start];
// 如果在同一个城市联盟内,那么把这个目标城市排除,在剩下的目标城市中继续
if (graph->same_league(start, target)) {
graph->adjacency[start][target] = INT_MAX;
continue;
}
// 如果已经修建过了,则换个目标城市
if (graph->incidence[start][target]) {
continue;
}
// 不需要考虑三个或以上成环的情况
break;
}
const int start_alpha = graph->get_alpha(start);
const int target_alpha = graph->get_alpha(target);
// 当城市规模系数α到达限定系数β后,我们认为该 league
// 已经到达“稳定”,不再与任何其他城市修建公路。
if (start_alpha >= graph->beta || target_alpha >= graph->beta) {
continue;
}
if (start_alpha < target_alpha) {
// 规模小于目标城市,则政府拒绝修建
continue;
}
else if (start_alpha == target_alpha) {
// 若两个城市规模相等,则修建过后两座城市形成的 league 城市规模系数α增一
graph->increase_alpha(start);
}
else if (start_alpha > target_alpha) {
// 若大于目标城市,则同意修建,规模系数不变
;
}
// 修建公路即在关系矩阵上将相应的行列置为true
graph->incidence[start][target] = graph->incidence[target][start] = true;
graph->incidence_had_changed = true; // 保护字段为什么能直接访问?
// 把目标城市所在联盟合并到起始城市所在联盟中
graph->merge(start, target);
}
}
int main() {
int n, beta;
std::cout << "输入城市的个数:";
std::cin >> n;
auto graph = ComplexGraph(n);
std::cout << "初始的城市规模为:" << std::endl;
graph.print_alpha();
std::cout << "请输入限定系数beta";
std::cin >> beta;
graph.set_beta(beta);
std::cout << "初始的距离的邻接矩阵为:" << std::endl;
graph.print_adjacency();
for (int turn_num = 1; ; turn_num++) {
graph.start_record_incidence();
one_turn(&graph);
// 当关系矩阵不再被改变,也就是说明不再修桥了,则说明达到稳定
if (!graph.stop_record_incidence()) {
break;
}
std::cout << "" << turn_num << "轮后的关系矩阵如下:" << std::endl;
graph.print_incidence();
std::cout << "规模系数如下:" << std::endl;
graph.print_alpha();
std::cout << "并查集如下:" << std::endl;
graph.print_merge_find_set();
std::cout << std::endl;
}
std::cout << "已经达到稳定" << std::endl;
return 0;
}
// 输入城市的个数10
// 初始的城市规模为:
// 城市联盟 { 0 } 的规模系数为 2
// 城市联盟 { 1 } 的规模系数为 5
// 城市联盟 { 2 } 的规模系数为 2
// 城市联盟 { 3 } 的规模系数为 1
// 城市联盟 { 4 } 的规模系数为 3
// 城市联盟 { 5 } 的规模系数为 4
// 城市联盟 { 6 } 的规模系数为 2
// 城市联盟 { 7 } 的规模系数为 2
// 城市联盟 { 8 } 的规模系数为 4
// 城市联盟 { 9 } 的规模系数为 3
// 请输入限定系数beta5
// 初始的距离的邻接矩阵为:
// 2147483647 63 39 34 97 93 35 42 68 29
// 63 2147483647 11 100 82 48 31 2 33 58
// 39 11 2147483647 85 100 27 47 97 86 91
// 34 100 85 2147483647 15 32 16 77 84 29
// 97 82 100 15 2147483647 4 53 63 54 29
// 93 48 27 32 4 2147483647 25 85 86 58
// 35 31 47 16 53 25 2147483647 97 27 88
// 42 2 97 77 63 85 97 2147483647 61 91
// 68 33 86 84 54 86 27 61 2147483647 66
// 29 58 91 29 29 58 88 91 66 2147483647
//
// 第1轮后的关系矩阵如下
// 0 0 0 0 0 0 0 0 0 1
// 0 0 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 1 0 0 0
// 0 0 0 0 0 1 0 0 0 0
// 0 0 0 0 1 0 0 0 0 0
// 0 0 0 1 0 0 0 0 1 0
// 0 0 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 1 0 0 0
// 1 0 0 0 0 0 0 0 0 0
//
// 规模系数如下:
// 城市联盟 { 1 } 的规模系数为 5
// 城市联盟 { 2 } 的规模系数为 2
// 城市联盟 { 4 5 } 的规模系数为 4
// 城市联盟 { 7 } 的规模系数为 2
// 城市联盟 { 3 6 8 } 的规模系数为 4
// 城市联盟 { 0 9 } 的规模系数为 3
// 并查集如下:
// 9 -1 -1 8 5 -1 8 -1 -1 -1
//
// 第2轮后的关系矩阵如下
// 0 0 0 0 0 0 0 0 0 1
// 0 0 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0 0 0
// 0 0 0 0 1 0 1 0 0 0
// 0 0 0 1 0 1 0 0 0 0
// 0 0 0 0 1 0 0 0 0 0
// 0 0 0 1 0 0 0 0 1 0
// 0 0 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 1 0 0 0
// 1 0 0 0 0 0 0 0 0 0
//
// 规模系数如下:
// 城市联盟 { 1 } 的规模系数为 5
// 城市联盟 { 2 } 的规模系数为 2
// 城市联盟 { 7 } 的规模系数为 2
// 城市联盟 { 3 4 5 6 8 } 的规模系数为 5
// 城市联盟 { 0 9 } 的规模系数为 3
// 并查集如下:
// 9 -1 -1 8 8 8 8 -1 -1 -1
//
// 已经达到稳定