【问题标题】:graph rerouting algorithm hacker rank图路由算法hackerrank
【发布时间】:2020-10-19 06:30:21
【问题描述】:

我已尝试解决黑客级别的重新路由问题。比赛结束后,我在这里发帖寻求帮助。

https://www.hackerrank.com/contests/hack-the-interview-v-asia-pacific/challenges/rerouting

我尝试使用强连接组件解决问题,但测试用例失败。我可以理解我们必须删除循环。但我坚持如何解决问题。以下是我写的解决方案。我正在寻找如何前进的指导,以便我可以根据我在这里犯的错误应用我的知识未来。感谢您的时间和帮助

int getMinConnectionChange(vector<int> connection) {
    
    // Idea: Get number of strongly connected components.
    int numberOfVertices = connection.size();
    for(int idx = 0; idx < numberOfVertices; idx++) {
        cout << idx+1 <<":"<< connection[idx] << endl;
    }
    stack<int> stkVertices; 
    map<int, bool> mpVertexVisited; //is vertex visited.think this as a chalk mark for nodes visited.
    
    
    int numOFSCCs = 0;
    int currTime = 1;
    for (int vertexId = 0; vertexId < numberOfVertices; vertexId++) {
        // check if node is already visited.
        if (mpVertexVisited.find(vertexId+1) == mpVertexVisited.end()) {
            numOFSCCs++;
            mpVertexVisited.insert(make_pair(vertexId+1, true));
            stkVertices.push(vertexId+1);
            currTime++;

            while (!stkVertices.empty()) {
                int iCurrentVertex = stkVertices.top();
                stkVertices.pop(); 
                // get adjacent vertices. In this excercise we have only one neighbour. i.e., edge
                int neighbourVertexId = connection[iCurrentVertex-1];
                // if vertex is already visisted, don't insert in to stack.
                if (mpVertexVisited.find(neighbourVertexId) != mpVertexVisited.end()) {
                    continue;
                }
                mpVertexVisited.insert(make_pair(neighbourVertexId, true));
                stkVertices.push(neighbourVertexId);            
            } // while loop
        } // if condition m_mapVrtxTimes.find(*itr) == m_mapVrtxTimes.end()
    } // for loop of vertices
    return numOFSCCs - 1;

}

【问题讨论】:

    标签: c++ algorithm graph graph-algorithm


    【解决方案1】:

    这是我刚刚解决的一个问题,想分享一下解决方案。

    这个问题可以用union-find解决。

    两个主要观察:

    1. 必须改变的边数是number of components - 1(不一定是强连接)Thus, union-find is handy here for finding the number of components
    2. 第二个观察是某些组件没有终止节点,考虑1&lt;-&gt;2,换句话说,存在一个循环。如果某个节点没有出边,我们可以检测是否存在终止节点。

    如果所有组件都有一个循环,这意味着我们需要更改每个组件而不是a number of components - 1。这是为了使图形有一个终止点。

    代码:

    struct UF {
        vector<int> p, rank, size;
        int cnt;
        UF(int N) {
            p = rank = size = vector<int>(N, 1);
            for (int i = 0; i < N; i++) p[i] = i;
            cnt = N;
        }
        int find(int i) {
            return p[i] == i ? i : p[i] = find(p[i]);
        }
        bool connected(int i, int j) {
            return find(i) == find(j);
        }
        void join(int i, int j) {
            if (connected(i, j)) return;
            int x = find(i), y = find(j);
            cnt--;
            if (rank[x] > rank[y]) {
                p[y] = x;
                size[x] += size[y];
            } else {
                p[x] = y;
                size[y] += size[x];
                if (rank[x] == rank[y]) rank[y]++;
            }
        }
    };
    
    int getMinConnectionChange(vector<int> connection) {
        int nonCycle = 0;
        int n = connection.size();
        UF uf(n);
        for(int i=0;i<n;i++) {
            int to = connection[i] - 1;
            if(to == i) nonCycle++;
            else uf.join(i, to);
        }
        int components = uf.cnt;
        int countCycle = uf.cnt - nonCycle;
        int res = components - 1;
        if(countCycle == components) res++; // all components have cycle
        return res;
    }
    

    【讨论】:

      【解决方案2】:

      TL;DR:您可以将其视为寻找minimal spanning arborescence problem

      更准确地说,为每个服务器添加一个节点,另一个称为“终止”。 制作一个完整的图表(每个节点都链接到其他每个节点)并将与您的输入对应的边设置为成本 0,其他边设置为 1。

      您可以使用例如Edmond's algorithm 来解决此问题。

      【讨论】:

      • 感谢您的意见。这里的 TL、DR 是什么意思
      • 如果可能,请您详细说明。谢谢
      猜你喜欢
      • 2015-11-05
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多