C++ 内存限制超出错误,无法从图中的每个组件中查找最大值
问题是: exmaple:C++ 内存限制超出错误,无法从图中的每个组件中查找最大值,c++,algorithm,graph,depth-first-search,union-find,C++,Algorithm,Graph,Depth First Search,Union Find,问题是: exmaple: 5 12 34 10 7 8 3 1 2 2 3 3 1 输出: 56 分组如下:[1,2,3][4][5] 最大收集量为56(由志愿者1、2和3收集) 我的逻辑是运行dfs并将图中所有组件中的最大值存储为我的ans 这是我的密码: #include <iostream> #include <vector> #include <unordered_map> using namespace std; int dfs(in
5
12 34 10 7 8
3
1 2
2 3
3 1
输出:
56
- 分组如下:[1,2,3][4][5]
- 最大收集量为56(由志愿者1、2和3收集)
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int dfs(int v, int values[], unordered_map<int, vector<int>> adj, int visited[])
{
int ans = 0;
if (visited[v] == 0)
{
visited[v] = 1;
for (auto j : adj[v])
{
if (visited[j] == 0)
{
ans = ans + dfs(j, values, adj, visited);
}
}
return ans + values[v];
}
return 0;
}
void solve()
{
int n;
cin >> n;
int v[n];
int visited[n];
for (int i = 0; i < n; i++)
{
visited[i] = 0;
}
//vector<vector<int>> adj(n);
unordered_map<int, vector<int>> adj;
for (int i = 0; i < n; i++)
{
cin >> v[i];
}
int p;
int ans = 0;
cin >> p;
while (p--)
{
int f, s;
cin >> f >> s;
f = f - 1;
s = s - 1;
adj[f].push_back(s);
adj[s].push_back(f);
}
for (int i = 0; i < n; i++)
{
if (visited[i] == 0)
{
int val = dfs(i, v, adj, visited);
if (val > ans)
{
ans = val;
}
}
}
// for (int i = 0; i < n; i++)
// {
// cout << i << " ";
// for (auto j : adj[i])
// {
// cout << j << " ";
// }
// cout << endl;
// }
cout << ans << endl;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// #ifndef ONLINE_JUDGE
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
// #endif // ONLINE_JUDGE
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
}
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
vector<int> parent;
vector<int> values;
vector<int> r;
int find(int s)
{
if (parent[s] == s)
{
return s;
}
return parent[s] = find(parent[s]);
}
void unite(int a, int b)
{
a = find(a);
b = find(b);
if (a != b)
{
if (r[a] < r[b])
{
parent[a] = parent[b];
r[b] = r[b] + r[a];
}
else
{
parent[b] = parent[a];
r[a] = r[a] + r[b];
}
}
}
void solve()
{
int n;
cin >> n;
parent.resize(n);
values.resize(n);
r.resize(n);
int ans = 0;
for (int i = 0; i < n; i++)
{
parent[i] = i;
}
for (int i = 0; i < n; i++)
{
cin >> values[i];
}
for (int i = 0; i < n; i++)
{
r[i] = 1;
}
int p;
cin >> p;
unordered_map<int, int> m;
while (p--)
{
int f, s;
cin >> f >> s;
f = f - 1;
s = s - 1;
int f1 = find(f);
int f2 = find(s);
if (f1 != f2)
{
unite(f1, f2);
}
}
for (int i = 0; i < n; i++)
{
if (m[parent[i]])
{
m[parent[i]] = m[parent[i]] + values[i];
ans = max(ans, m[parent[i]]);
}
else
{
m[parent[i]] = values[i];
ans = max(ans, m[parent[i]]);
}
}
cout << ans << endl;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif // ONLINE_JUDGE
solve();
}
有人能告诉我哪里错了吗?不幸的是,我不能遵循你的方法。对此我非常抱歉 无论如何,我建议使用一种不同的算法,基于“循环置换”。眼前的问题是使用这种方法。有关说明,您可以阅读维基百科上的文章 “资金收集”的附加内容只是进一步的间接操作,与要解决的问题无关 基本任务是创建组或团 维基百科文章中描述的方法是使用。因为在给定的问题中,只使用了索引,所以最终生活会更加轻松。我暂时忘记了基于1的开始索引,在后面的程序中只使用偏移量 那么,给定的输入在双线表示法中会是什么样子呢
1 2 3 4 5
2 3 1 4 5
我们怎样才能用这个符号找到群和圈呢。我们开始迭代第一行中的所有值。对于第一个索引1,我们存储数据,然后在1下查找并找到一个2。在这2行中,我们再次在第一行中搜索,存储它,然后在它下面查看。在那里我们找到了3。把3号放好,看看下面。我们找到一个1。搜索1并尝试存储它,但它已存在。因此,停止计算第一行的第一个值。由此产生的goup为1-2-3
然后继续第一行中的下一个值。通过上述方法,我们将得到2-3-1。对于第1行中的下一个值,我们将得到3-1-2,然后只有4个,只有5个。所以,循环群是(1,2,3),(4),(5)
非常简单。为了避免重复的循环/组,我们将循环存储在std::set
中。因此,所有cylce/组成员都将是唯一的,并进行排序。如果我们以后想优化算法,这一点很重要。我们可以检查第一行的条目是否已经是周期/组的成员。那么这个评估就没有必要了。这可以节省大量志愿者的工作
另一方面,我们需要存储所有周期/组,并在此集合中进行搜索。因此,这也将花费空间和时间。我不确定,目前有什么更好的。但是我将检查保留在下面显示的示例代码中
下一步优化。我们根本不需要两条线。因为只存储索引。所以,第一行总是简单的索引1…志愿者的数量。如果我们读入对值,那么我们将对的第二个值存储在索引中,由对的第一个值表示。为了不遗漏其余的值,我们在开始时使用std::iota
初始化基本std:::vector
因此,我们初始化我们的std::vector
。内容是1,2,3,4,5,然后我们读1,2。意思是将第二个值2放在索引1处。内容现在是2,2,3,4,5。然后读2,3。也就是说,将对3的第二个值放在位置2。内容现在是2,3,3,4,5。接下来是3,1。所以把1放在位置3。内容现在是2,3,1,4,5。因为没有更多的输入,这是最终的输入序列
以及上述评估。我们现在迭代这个std::vector
中的所有元素。我们从索引1开始,将该值存储在cycle/group中。在索引1处,我们找到了一个2。新的索引将是2。将其添加到循环/组(现在:1,2)。什么是索引2?对,三。将其添加到循环/组(现在:1,2,3)。在索引3处,我们找到值1。这已经在我们的周期/组中,因此我们停止对第一个索引的评估。第一个循环/组为(1,2,3)
然后,我们转到下一个索引,得到2,3,1。我们在astd::set
中存储值,因此我们将再次得到1,2,3。无需进一步评估
等等等等
在找到一个循环/组后,我们根据循环/组中的索引计算集合的总和。并且,将此总和与当前最大值进行比较,如果需要,我们将更新该值
基本上,我们不需要存储所有的周期/组,但它可以提高执行速度(尽管我不确定)
示例代码可能如下所示:
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <numeric>
#include <set>
#include <limits>
// Simulation of input data
std::istringstream inputData{R"(5
12 34 10 7 8
3
1 2
2 3
3 1)"};
// Functionality
int main() {
// All the following is the input handling -----------------------------------------------------------
size_t numberOfVolunteers{}; inputData >> numberOfVolunteers; // Read group size
std::vector<int>collections(numberOfVolunteers); // Get all "collection" values
std::copy_n(std::istream_iterator<int>(inputData), numberOfVolunteers, collections.begin());
size_t numberOfPairs{}; inputData >> numberOfPairs; // Number of pairs to read
std::vector<size_t> permutations(numberOfVolunteers); // Initialize our permutations vector
std::iota(permutations.begin(), permutations.end(), 0);
for (size_t i{}; i < numberOfPairs; ++i) { // Get all cyclic permutations
size_t index{}; size_t target{}; inputData >> index >> target;
permutations[index - 1] = target - 1;
}
// Input done, now start algorithm -----------------------------------------------------------
std::vector<std::set<size_t>> allCycles{}; // All unique cycles / group of volunteers
int maxSum{ std::numeric_limits<int>::min() }; // And thsi will be the result of the program
// Go through all entries of the whole group
for (size_t currentIndex = 0U; (currentIndex < numberOfVolunteers); ++currentIndex) {
// If this menmber is already part of a cylce/group, then do not make an evaluation again
if (std::count_if(allCycles.begin(), allCycles.end(), [&](const std::set<size_t>& c) {return c.count(currentIndex); }) == 0) {
std::set<size_t> cycle{}; // Here we will store one cycle / group of volunteers
size_t index = currentIndex; // And we will follow the chain of successors starting with current index
// As long as we find successors
for (bool insertResult{ true }; insertResult; ) {
const auto& [newElement, insertOk] = cycle.insert(index); // Insert new group member
index = permutations[index]; // Set next successor
insertResult = insertOk; // Continue?
}
//Calculate the sum of the collections for this Cycle / Group
int sum{}; for (size_t index : cycle) sum += collections[index];
maxSum = std::max(sum, maxSum);
// Debug Output. Please uncomment, if you want to see debug output
std::cout << "Cycle: "; for (size_t index : cycle) std::cout << index + 1 << ' '; std::cout << " Sum: " << sum << " MaxSum : " << maxSum << '\n';
// Save current cycle
allCycles.emplace_back(std::move(cycle));
}
std::cout << maxSum << '\n'; // Show result
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//输入数据的模拟
std::istringstream输入数据{R'(5
12 34 10 7 8
3.
1 2
2 3
3 1)"};
//功能性
int main(){
//以下是输入处理-----------------------------------------------------------
大小\u t NumberOf志愿者{};inputData>>NumberOf志愿者;//读取组大小
std::vectorcollections(NumberOfVolumers);//获取所有“集合”值
std::copy_n(std::istream_迭代器(inputData)、numberof志愿者、collections.begin());
大小\u t numberOfPairs{};inputData>>numberOfPairs;//要读取的对数
std::向量置换(numberOfIvorites);//初始化我们的置换向量
std::iota(permutations.begin(),permutations.end(),0);
对于(size_t i{};i>索引>>目标;
置换[索引-1]=目标-1;
}
//输入完成,现在开始算法-----------------------------------------------------------
std::vector allCycles{};//所有唯一的周期/志愿者组
int maxSum{std::numeric_limits::min()};//和thsi将是程序的结果
//检查整个小组的所有条目
对于(大小\u t currentIndex=0U;(currentIndex#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
#define MAX_NODE 10005
unordered_map<int, vector<int>> adj;
int values[MAX_NODE];
int visited[MAX_NODE];
int dfs(int v)
{
int ans = values[v];
visited[v] = 1;
for (auto j : adj[v])
{
if (visited[j] == 0)
{
ans = ans + dfs(j);
}
}
return ans;
}
void solve()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> values[i];
visited[i] = 0;
}
int p;
int ans = 0;
cin >> p;
while (p--)
{
int f, s;
cin >> f >> s;
f = f - 1;
s = s - 1;
adj[f].push_back(s);
adj[s].push_back(f);
}
for (int i = 0; i < n; i++)
{
if (visited[i] == 0)
{
int val = dfs(i);
if (val > ans)
{
ans = val;
}
}
}
cout << ans << endl;
adj.clear();
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// #ifndef ONLINE_JUDGE
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
// #endif // ONLINE_JUDGE
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
}
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
vector<int> parent;
vector<int> values;
vector<int> r;
unordered_map<int, int> m;
int find(int s)
{
if (parent[s] == s)
{
return s;
}
return parent[s] = find(parent[s]);
}
void unite(int a, int b)
{
a = find(a);
b = find(b);
if (a != b)
{
if (r[a] < r[b])
{
parent[a] = b;
}
else if(r[a] > r[b])
{
parent[b] = a;
}
else
{
parent[b] = a;
r[a] += 1;
}
}
}
void solve()
{
int n;
cin >> n;
parent.resize(n);
values.resize(n);
r.resize(n);
int ans = 0;
for (int i = 0; i < n; i++)
{
cin >> values[i];
parent[i] = i;
r[i] = 1;
}
int p;
cin >> p;
while (p--)
{
int f, s;
cin >> f >> s;
f = f - 1;
s = s - 1;
int f1 = find(f);
int f2 = find(s);
if (f1 != f2)
{
unite(f1, f2);
}
}
// compression one more time to confirm the integrary of group number
for (int i = 0; i < n; i++) find(i);
for (int i = 0; i < n; i++)
{
if (m.find(parent[i]) != m.end())
{
m[parent[i]] = m[parent[i]] + values[i];
ans = max(ans, m[parent[i]]);
}
else
{
m[parent[i]] = values[i];
ans = max(ans, m[parent[i]]);
}
}
cout << ans << endl;
m.clear();
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// #ifndef ONLINE_JUDGE
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
// #endif // ONLINE_JUDGE
solve();
}