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 externo)
- 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;
}