|
|
- //
- // 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
- //
- // 已经达到稳定
|