检查有向图CS50 tideman中是否存在循环

问题描述 投票:1回答:1

以检查程序从图的第一个节点到图的每个锁定节点的周期->检查它是否在之前访问过,然后是一个循环,然后从检查的下一个节点递归重复。当我自己测试它时,它可以工作,但是当我在潮人选举中使用时,它就没有效果。

问题的解释:https://cs50.harvard.edu/x/2020/psets/3/tideman/

此问题的目标是使用潮汐投票算法从选举中选出胜者。 CS50 ide提供了测试功能Check50,我正在尝试修复以下错误: 1.lock_pairs如果创建循环则跳过最后一对 2.lock_pairs如果创建周期则跳过中间对。

我的逻辑错了吗?

int graph[nodes_count][nodes_count];
bool check_cycle()
{
    //if a node is visited during checking cycles visited[]=true
    bool visited[nodes_count];
    bool circle = false;
    return gointo(circle, visited, 0);
}
bool gointo(bool &circle, bool visited[], int to)
{
// start trip form one node in the graph check if it have been visited ( Cycle )
    visited[to] = true;
    for (int n = 0; n < nodes_count; n++)
    {
        if (graph[to][n])
        {
            if (visited[n])
            {
                circle = true;
            }
            else
            {
                gointo(visited, n);
            }
            break;
        }
    }

    return circle;
}

我的完整解决方案:https://pastebin.com/sbua3EGA谢谢您的时间,对不起,英语不好:)

c algorithm cs50 adjacency-matrix directed-graph
1个回答
0
投票

您的算法在无向图中是正确的。在有向图中并不那么明显。

首先,从节点0开始,您可能不会访问所有节点。反例: 1-> 0-> 2

从节点0开始检查时,您将根本不会访问1。如果1也有一个循环的沿,您将不会检测到它。这意味着,您应该为每个顶点进行循环,如果尚未访问,请运行“ gointo”功能。

通过上述更改,您可能最终会在没有循环时找到循环。

例如:

1-> 2-> 3

4-> 2

如果首先执行gointo(1),则将1、2和3标记为已访问。然后,当调用gointo(4)时,您将“检测到一个循环”,因为4具有已标记顶点的边。因此,您需要两个数组,一个数组告诉您已经访问了该节点,另一个数组告诉该节点在此特定的gointo调用中已被访问。

代码应如下所示:

int graph[nodes_count][nodes_count];
bool check_cycle()
{
    //if a node is visited during checking cycles visited[]=true
    bool visited[nodes_count];
    bool this_call[nodes_count];
    bool circle = false;
    for (int i = 0; i < nodes_count; ++i)
    {
         if(!visited[i] && gointo(circle, visited, i))
           return true;
    }
    return false;
}
bool gointo(bool &circle, bool visited[], int to)
{
// start trip form one node in the graph check if it have been visited ( Cycle )
    visited[to] = true;
    this_call[to] = true;
    for (int n = 0; n < nodes_count; n++)
    {
        if (graph[to][n])
        {
            if (visited[n] && this_call[n])
            {
                circle = true;
            }
            else if(!visited[n])
            {
                gointo(visited, n);
            }
        }
    }
    this_call[to] = false;
    return circle;
}
© www.soinside.com 2019 - 2024. All rights reserved.