Rank
Explicación
Podemos usar los partidos para construir un grafo dirigido. Si gana contra , construimos una arista de a . Como las cotas de y son pequeñas, podemos iniciar una DFS desde cada vértice. Si volvemos a alcanzar ese vértice, lo marcamos como “cíclico” y lo contamos en el resultado.
Implementación
tiempo
#include <iostream>
#include <vector>
using namespace std;
const int MAX_N = 20;
vector<vector<int>> adj(MAX_N);
bool vis[MAX_N], cyclic[MAX_N];
int original_node;
void dfs(int node) {
vis[node] = true;
// se encontró un ciclo
if (node == original_node) {
cyclic[node] = true;
return;
}
for (int u : adj[node]) {
if (!vis[u]) dfs(u);
}
}
int main() {
int n, k;
cin >> n >> k;
// procesar el grafo dirigido
for (int i = 0; i < k; i++) {
int a, b, sa, sb;
cin >> a >> b >> sa >> sb;
if (sa > sb) {
adj[b - 1].push_back(a - 1);
} else if (sa < sb) {
adj[a - 1].push_back(b - 1);
}
}
for (int i = 0; i < n; i++) {
original_node = i;
fill(begin(vis), end(vis), false);
for (int u : adj[i]) { dfs(u); }
}
// contar la cantidad de nodos cíclicos.
int ans = 0;
for (int i = 0; i < n; i++) {
if (cyclic[i]) ans++;
}
cout << ans << endl;
}n, m = map(int, input().split())
adj = [[] for _ in range(n)]
vis, cyclic = [False for _ in range(n)], [False for _ in range(n)]
original_node = -1
def dfs(node):
if vis[node]:
return
vis[node] = True
# se encontró un ciclo
if node == original_node:
cyclic[node] = True
for u in adj[node]:
if not vis[u]:
dfs(u)
# procesar el grafo dirigido
for i in range(m):
a, b, sa, sb = map(int, input().split())
if sa > sb:
adj[b - 1].append(a - 1)
elif sb > sa:
adj[a - 1].append(b - 1)
for i in range(n):
original_node = i
vis = [False for _ in range(n)]
for u in adj[i]:
dfs(u)
ans = 0
for i in range(n):
if cyclic[i]:
ans += 1
print(ans)import java.io.*;
import java.util.*;
public class Rank {
static Map<Integer, HashSet<Integer>> graph = new HashMap<>();
static int ans = 0;
static Set<Integer> visited = new HashSet<>();
static boolean cyclic = false;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int people = Integer.parseInt(st.nextToken());
int games = Integer.parseInt(st.nextToken());
for (int x = 0; x < games; x++) {
st = new StringTokenizer(br.readLine());
int p1 = Integer.parseInt(st.nextToken()); // Persona 1
int p2 = Integer.parseInt(st.nextToken()); // Persona 2
int p1s = Integer.parseInt(st.nextToken()); // puntaje de la Persona 1
int p2s = Integer.parseInt(st.nextToken()); // puntaje de la Persona 2
int winner;
int loser;
if (p1s > p2s) {
winner = p1;
loser = p2;
} else {
winner = p2;
loser = p1;
}
if (!graph.containsKey(winner)) { graph.put(winner, new HashSet<>()); }
// El grafo debe poner una arista de ganador -> perdedor
graph.get(winner).add(loser);
}
for (int x = 1; x <= people; x++) {
// Contar nodos cíclicos
cyclic = false;
visited = new HashSet<>();
if (dfs(x, x)) { ans++; }
}
System.out.println(ans);
}
public static boolean dfs(int current, int start) {
// Seguir recorriendo el grafo hasta que o bien se encuentre
// el nodo inicial, o bien se hayan visitado todos los nodos
if (visited.contains(current) && current == start) {
// Es cíclico
cyclic = true;
return true;
}
if (visited.contains(current)) {
// Visitado pero no cíclico
return true;
}
visited.add(current);
if (!graph.containsKey(current)) { graph.put(current, new HashSet<>()); }
for (int x : graph.get(current)) { dfs(x, start); }
return cyclic;
}
}