Programação pensando semana7 lição de casa A-game tabela de vitórias e derrotas

Título

O Magic Cat diz ao TT que ele realmente tem uma tabela de perdas e ganhos de jogo com N indivíduos e relacionamentos de perda e ganho de M. Cada relacionamento de perda e ganho é AB, indicando que A pode ganhar B e o relacionamento de perda e perda é transitivo. Ou seja, A vence B e B vence C, para que A possa vencer C.
TT não acredita que seu gatinho possa prever qualquer jogo, então ele quer saber quantos resultados de jogadores não podem ser conhecidos antecipadamente. Você pode ajudá-lo?

Entrada

A primeira linha fornece o número de grupos de dados.
A primeira linha de cada conjunto de dados fornece N e M (N, M <= 500).
Nas próximas linhas M, cada linha recebe AB, indicando que A pode vencer B.

Ouput

Para cada conjunto de dados, é impossível saber antecipadamente quantos jogos são ganhos ou perdidos. Observe que (a, b) é equivalente a (b, a), ou seja, cada binário é calculado apenas uma vez.

Entrada de amostra

3
3 3
1 2
1 3
2 3
3 2
1 2
2 3
4 2
1 2
3 4

Amostra Ouput

0
0
4

Idéias

Considerando cada jogador como um ponto, se o jogador A puder vencer o jogador B, haverá uma vantagem direcionada do ponto A ao ponto B. Em seguida, o problema é abstraído como se dois pontos do gráfico direcionado estão conectados .
Usando o algoritmo floyd, altere a distância entre dois pontos para descobrir se há uma conexão direcional entre os dois pontos.
O código alterado é:

void floyd(int& ans){
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            if(dis[i][k]==1){
                for(int j=1;j<=n;j++){
                    if(dis[k][j]==1&&dis[i][j]!=1){
                        dis[i][j]=1;
                        ans++;
                    }
                }
            }
        }
    }
}

Note quePodaSedis [i] [k]! = 1, Significado desgasteNão há aresta direcionada onde i aponta para k, Sem mencionar que i-> j é derivado de i-> k e k-> j.

Floyd-Warshall

  • Oficial:f [x] [y] = min (f [x] [y], f [x] [k] + f [k] [y]). A distância de x até y é atualizada para ser a menor da distância original de x para y e a distância de x para y quando é permitido passar pelos nós 1 a k. Ou seja, a distância entre os dois pontos correspondentes à aresta de inicialização é removida e a distância entre os dois pontos restantes é atribuída como + ∞. Atualize continuamente a distância entre dois pontos: quando k = n, a atualização termina.
  • Implementação do algoritmo (observaçãok é o ciclo mais externoInsira a descrição da imagem aqui
  • Aplicação: usado para encontrar a figuraA relação entre dois pontos: Fonte múltipla mais curta, qualquerRelação de distância entre dois pontos; Fechamentos transitivos no gráfico, arbitráriosConectividade de dois pontos

Código

#include <cstdio>
#include <algorithm>
using namespace std;
int dis[505][505];
int n,m;

void floyd(int& ans){
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            if(dis[i][k]==1){
                for(int j=1;j<=n;j++){
                    if(dis[k][j]==1&&dis[i][j]!=1){
                        dis[i][j]=1;
                        ans++;
                    }
                }
            }
        }
    }
}

int main(){
    int num;
    scanf("%d",&num);
    for(int i=0;i<num;i++){
        memset(dis,0,sizeof(dis));
        scanf("%d%d",&n,&m);
        for(int j=0;j<m;j++){
            int a,b;
            scanf("%d%d",&a,&b);
            dis[a][b]=1;
        }
        int ans=m;
        floyd(ans);
        printf("%d\n",n*(n-1)/2-ans);
    }
    return 0;
}

Link do título

Publicado 24 artigos originais · elogiado 2 · visitas 435

Acho que você gosta

Origin blog.csdn.net/weixin_43805228/article/details/105398531
Recomendado
Clasificación