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

94 lines
3.9 KiB
C++
Raw Normal View History

2023-12-02 19:58:55 +08:00
/*
*
* 1. 使merge或者inplace_merge
* 2. 使priority_queue
* 3. 使multiset
*
* $n$$n^2$
* n-1
* merge吧
*/
/*
*
* ABC三个城市存在环A申请修建ABB申请修建BCC申请修建CA
* AB < AC, BC < BA, CA < CB
* AB < AC < BC < ABAB < AB是不可能的
* n个城市n > 2
*/
/*
* n个城市一轮后就会修建了
* n条公路n-1使
*/
#include <iostream>
#include "graph.hpp"
// 一轮
void one_turn(Graph* 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;
}
// 修建公路即在关系矩阵上将相应的行列置为true
graph->incidence[start][target] = graph->incidence[target][start] = true;
// 把目标城市所在联盟合并到起始城市所在联盟中
graph->merge(start, target);
}
}
int main() {
int n;
std::cout << "输入城市的个数:";
std::cin >> n;
auto graph = Graph(n);
std::cout << "初始的距离的邻接矩阵为:" << std::endl;
graph.print_adjacency();
one_turn(&graph);
std::cout << "第一轮后的关系矩阵如下:" << std::endl;
graph.print_incidence();
std::cout << "并查集如下:" << std::endl;
graph.print_merge_find_set();
std::cout << "可以看到,一轮后就已经全部连通。" << std::endl;
return 0;
}
// 输入城市的个数5
// 初始的距离的邻接矩阵为:
// 2147483647 69 19 14 90
// 69 2147483647 66 82 66
// 19 66 2147483647 48 8
// 14 82 48 2147483647 22
// 90 66 8 22 2147483647
//
// 第一轮后的关系矩阵如下:
// 0 0 0 1 0
// 0 0 1 0 0
// 0 1 0 0 1
// 1 0 0 0 1
// 0 0 1 1 0
//
// 并查集如下:
// -1 0 0 0 0
// 可以看到,一轮后就已经全部连通。