// // Created by 423A35C7 on 2023-12-02. // #include #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 // // 已经达到稳定