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

📅  最后修改于: 2021-04-23 06:13:28             🧑  作者: Mango

给定大小为N的成对arr阵列,代表第一位玩家与第二位玩家获胜的比赛情况。给定多个查询,每个查询包含两个数字,任务是确定如果彼此竞争,哪个将获胜。

笔记:

  • 如果A胜过B并且B胜过C ,那么A总是胜过C。
  • 如果A胜过BA胜过C ,如果与BC比赛,并且如果我们无法确定获胜者,则人数较小的玩家获胜

例子:

先决条件:拓扑排序

方法:
假设所有输入均有效。现在建立一个图形。如果玩家X胜过玩家Y,那么我们将玩家X的优势添加到玩家Y。构建图后,请进行拓扑排序。对于形式(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