📜  寻找比赛的获胜者 |多个查询

📅  最后修改于: 2021-10-25 05:02:34             🧑  作者: Mango

给定一个大小为N的对 arr数组,它表示第一个玩家战胜第二个玩家的游戏情况。给定多个查询,每个查询包含两个数字,任务是确定如果它们相互竞争,哪一个将获胜。
笔记:

  • 如果A战胜B并且B战胜C ,那么A将永远战胜C
  • 如果A战胜B并且A战胜C ,如果BC有比赛,如果我们无法确定获胜者,那么数字较小的玩家获胜

例子:

先决条件:拓扑排序
方法:
让我们假设所有输入都是有效的。现在构建一个图形。如果playerX 战胜playerY,那么我们添加一条从playerX 到playerY 的边。构建图后进行拓扑排序。对于 (x, y) 形式的每个查询,我们检查在拓扑排序中哪个数字 x 或 y 排在前面并打印答案。
下面是上述方法的实现:

C++
// C++ program to find winner of the match
#include 
using namespace std;
 
// Function to add edge between two nodes
void add(vector adj[], int u, int v)
{
    adj[u].push_back(v);
}
 
// Function returns topological order of given graph
vector topo(vector adj[], int n)
{
    // Indeg vector will store
    // indegrees of all vertices
    vector indeg(n, 0);
    for (int i = 0; i < n; i++) {
        for (auto x : adj[i])
            indeg[x]++;
    }
    // Answer vector will have our
    // final topological order
    vector answer;
 
    // Visited will be true if that
    // vertex has been visited
    vector visited(n, false);
 
    // q will store the vertices
    // that have indegree equal to zero
    queue q;
    for (int i = 0; i < n; i++) {
        if (indeg[i] == 0) {
            q.push(i);
            visited[i] = true;
        }
    }
 
    // Iterate till queue is not empty
    while (!q.empty()) {
        int u = q.front();
        // Push the front of queue to answer
        answer.push_back(u);
        q.pop();
 
        // For all neighbours of u, decrement
        // their indegree value
        for (auto x : adj[u]) {
            indeg[x]--;
 
            // If indegree of any vertex becomes zero and
            // it is not marked then push it to queue
            if (indeg[x] == 0 && !visited[x]) {
                q.push(x);
                // Mark this vertex as visited
                visited[x] = true;
            }
        }
    }
 
    // Return the resultant topological order
    return answer;
}
// Function to return the winner between u and v
int who_wins(vector topotable, int u, int v)
{
    // Player who comes first wins
    for (auto x : topotable) {
        if (x == u)
            return u;
        if (x == v)
            return v;
    }
}
 
// Driver code
int main()
{
    vector adj[10];
 
    // Total number of players
    int n = 7;
 
    // Build the graph
    // add(adj, x, y) means x wins over y
    add(adj, 0, 1);
    add(adj, 0, 2);
    add(adj, 0, 3);
    add(adj, 1, 5);
    add(adj, 2, 5);
    add(adj, 3, 4);
    add(adj, 4, 5);
    add(adj, 6, 0);
 
    // Resultant topological order in topotable
    vector topotable = topo(adj, n);
 
    // Queries
    cout << who_wins(topotable, 3, 5) << endl;
    cout << who_wins(topotable, 1, 2) << endl;
 
    return 0;
}


Python3
# Python3 program to find winner of the match
 
# Function to add edge between two nodes
def add(adj, u, v):
    adj[u].append(v)
 
# Function returns topological order of given graph
def topo(adj, n):
 
    # Indeg vector will store
    # indegrees of all vertices
    indeg = [0 for i in range(n)]
    for i in range(n):
        for x in adj[i]:
            indeg[x] += 1
 
    # Answer vector will have our
    # final topological order
    answer = []
 
    # Visited will be true if that
    # vertex has been visited
    visited = [False for i in range(n)]
 
    # q will store the vertices
    # that have indegree equal to zero
    q = []
    for i in range(n):
        if (indeg[i] == 0):
            q.append(i)
            visited[i] = True
 
    # Iterate till queue is not empty
    while (len(q) != 0):
        u = q[0]
 
        # Push the front of queue to answer
        answer.append(u)
        q.remove(q[0])
 
        # For all neighbours of u, decrement
        # their indegree value
        for x in adj[u]:
            indeg[x] -= 1
 
            # If indegree of any vertex becomes zero and
            # it is not marked then push it to queue
            if (indeg[x] == 0 and visited[x] == False):
                q.append(x)
 
                # Mark this vertex as visited
                visited[x] = True
 
    # Return the resultant topological order
    return answer
 
# Function to return the winner between u and v
def who_wins(topotable, u, v):
    # Player who comes first wins
    for x in topotable:
        if (x == u):
            return u
        if (x == v):
            return v
 
# Driver code
if __name__ == '__main__':
    adj = [[] for i in range(10)]
 
    # Total number of players
    n = 7
 
    # Build the graph
    # add(adj, x, y) means x wins over y
    add(adj, 0, 1)
    add(adj, 0, 2)
    add(adj, 0, 3)
    add(adj, 1, 5)
    add(adj, 2, 5)
    add(adj, 3, 4)
    add(adj, 4, 5)
    add(adj, 6, 0)
 
    # Resultant topological order in topotable
    topotable = topo(adj, n)
 
    # Queries
    print(who_wins(topotable, 3, 5))
    print(who_wins(topotable, 1, 2))
 
# This code is contributed by Surendra_Gangwar


输出:
3
1

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。