用于存放学校的作业便于复习。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

160 lines
7.3 KiB

//
// 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
// 请输入限定系数beta:5
// 初始的距离的邻接矩阵为:
// 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
//
// 已经达到稳定