Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内存限制超出错误,无法从图中的每个组件中查找最大值_C++_Algorithm_Graph_Depth First Search_Union Find - Fatal编程技术网

C++ 内存限制超出错误,无法从图中的每个组件中查找最大值

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

问题是:

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(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。我们在a
std::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();
}