-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHuaZi2403.cpp
103 lines (90 loc) · 3.02 KB
/
HuaZi2403.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
using namespace std;
// 检测环
void detectCycles(int start, vector<int>& edges, vector<bool>& visited, vector<bool>& inStack, vector<int>& stack, vector<vector<int>>& cycles) {
int current = start;
// 循环直到遇到已访问过的节点
while (!visited[current]) {
visited[current] = true;
inStack[current] = true;
stack.push_back(current);
current = edges[current]; // 转移到下一个节点
}
if (inStack[current]) { // 检测到一个环
auto it = find(stack.begin(), stack.end(), current);
if (it != stack.end()) {
// 将环的节点添加到 cycles 中
cycles.emplace_back(it, stack.end());
}
}
// 标记栈中的所有节点为不在环中
for (int x : stack) {
inStack[x] = false;
}
stack.clear(); // 清空栈
}
// 找到最佳环
vector<int> findBestCycle(int n, vector<int>& edges) {
vector<bool> visited(n, false);
vector<bool> inStack(n, false);
vector<vector<int>> cycles;
vector<int> stack;
// 对于每个节点,检测是否存在环
for (int i = 0; i < n; i++) {
if (!visited[i]) {
detectCycles(i, edges, visited, inStack, stack, cycles);
}
}
// 找到具有最高内聚力值的环
int bestIndex = -1;
int bestValue = INT_MIN;
int maxMember = INT_MIN;
for (int i = 0; i < cycles.size(); ++i) {
const auto& cycle = cycles[i];
int L = cycle.size(); // 环的长度
unordered_set<int> uniqueVisitors;
// 统计环中访问过的节点(不包括环中的节点)
for (int node : cycle) {
int target = edges[node];
if (find(cycle.begin(), cycle.end(), target) == cycle.end()) {
uniqueVisitors.insert(target);
}
}
int V = uniqueVisitors.size(); // 访问过的节点数
int H = L - V; // 内聚力值
int currentMaxMember = *max_element(cycle.begin(), cycle.end()); // 最大成员编号
// 比较基于内聚力值和最大成员的大小
if (H > bestValue || (H == bestValue && currentMaxMember > maxMember)) {
bestIndex = i;
bestValue = H;
maxMember = currentMaxMember;
}
}
if (bestIndex != -1) {
auto& bestCycle = cycles[bestIndex];
// 将环旋转使最小节点为起始节点
rotate(bestCycle.begin(), min_element(bestCycle.begin(), bestCycle.end()), bestCycle.end());
return bestCycle;
}
return {}; // 没有找到环
}
int main() {
int n;
cin >> n;
vector<int> edges(n);
// 读取每个节点的连接节点
for (int i = 0; i < n; ++i) {
cin >> edges[i];
}
// 找到最佳环并输出
vector<int> bestCycle = findBestCycle(n, edges);
for (size_t i = 0; i < bestCycle.size(); ++i) {
if (i > 0) cout << " ";
cout << bestCycle[i];
}
cout << endl;
return 0;
}