Piggy Back
Solución en video
Por David Zhou
Video de YouTube (7IHPKEPe1w0)
Código de la solución en video
#include <climits>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
vector<vector<int>> adj;
void bfs(int start, vector<int> &dist) {
dist[start] = 0;
queue<int> q;
q.push(start);
while (!q.empty()) {
int curr = q.front();
q.pop();
for (int next : adj[curr]) {
if (dist[next] == -1) {
dist[next] = dist[curr] + 1;
q.push(next);
}
}
}
}
int main() {
// E/S antigua
freopen("piggyback.in", "r", stdin);
freopen("piggyback.out", "w", stdout);
int B, E, P, n, m;
cin >> B >> E >> P >> n >> m;
adj.resize(n);
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
adj[--a].push_back(--b);
adj[b].push_back(a);
}
vector<int> bessie_dist(n, -1), elsie_dist(n, -1), barn_dist(n, -1);
// BFS desde cada punto de partida
bfs(0, bessie_dist);
bfs(1, elsie_dist);
bfs(n - 1, barn_dist);
int res = INT_MAX;
for (int i = 0; i < n; i++) {
int b_dist = bessie_dist[i] * B, e_dist = elsie_dist[i] * E;
int barn =
barn_dist[i] * min(B + E, P); // P puede no ser más óptimo que B + E
res = min(res, b_dist + e_dist + barn);
}
cout << res << endl;
}import java.io.*;
import java.util.*;
public class Piggyback {
static List<List<Integer>> adj;
public static void bfs(int start, int[] dist) {
Arrays.fill(dist, -1);
dist[start] = 0;
Queue<Integer> q = new LinkedList<>();
q.add(start);
while (!q.isEmpty()) {
int curr = q.poll();
for (int next : adj.get(curr)) {
if (dist[next] == -1) {
dist[next] = dist[curr] + 1;
q.add(next);
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("piggyback.in"));
PrintWriter pw =
new PrintWriter(new BufferedWriter(new FileWriter("piggyback.out")));
StringTokenizer st = new StringTokenizer(br.readLine());
int B = Integer.parseInt(st.nextToken());
int E = Integer.parseInt(st.nextToken());
int P = Integer.parseInt(st.nextToken());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
adj = new ArrayList<>();
for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken()) - 1;
int b = Integer.parseInt(st.nextToken()) - 1;
adj.get(a).add(b);
adj.get(b).add(a);
}
int[] bessieDist = new int[n];
int[] elsieDist = new int[n];
int[] barnDist = new int[n];
// BFS desde cada punto de partida
bfs(0, bessieDist);
bfs(1, elsieDist);
bfs(n - 1, barnDist);
int res = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
int bCost = bessieDist[i] * B;
int eCost = elsieDist[i] * E;
int pCost = barnDist[i] *
Math.min(B + E, P); // P puede no ser más óptimo que B + E
res = Math.min(res, bCost + eCost + pCost);
}
pw.println(res);
pw.close();
br.close();
}
}from collections import deque
def bfs(start, dist, adj):
dist[start] = 0
q = deque([start])
while q:
curr = q.popleft()
for neighbor in adj[curr]:
if dist[neighbor] == -1:
dist[neighbor] = dist[curr] + 1
q.append(neighbor)
def main():
with open("piggyback.in", "r") as fin:
B, E, P, n, m = map(int, fin.readline().split())
adj = [[] for _ in range(n)]
for _ in range(m):
a, b = map(int, fin.readline().split())
a -= 1
b -= 1
adj[a].append(b)
adj[b].append(a)
bessie_dist = [-1] * n
elsie_dist = [-1] * n
barn_dist = [-1] * n
# BFS desde cada punto de partida
bfs(0, bessie_dist, adj)
bfs(1, elsie_dist, adj)
bfs(n - 1, barn_dist, adj)
res = float("inf")
for i in range(n):
b_cost = bessie_dist[i] * B
e_cost = elsie_dist[i] * E
p_cost = barn_dist[i] * min(B + E, P) # P puede no ser más óptimo que B + E
res = min(res, b_cost + e_cost + p_cost)
with open("piggyback.out", "w") as fout:
fout.write(f"{res}\n")
if __name__ == "__main__":
main()Explicación
Podemos hacer BFS desde los tres puntos de Bessie, Elsie y el granero. Al hacerlo, determinamos la distancia desde estos tres puntos hasta todos los demás. Después, recorremos todas las celdas y comprobamos la energía gastada si esa fuera la ubicación de encuentro.
Implementación
Complejidad temporal:
#include <bits/stdc++.h>
using namespace std;
unordered_map<int, vector<int>> mp;
vector<vector<int>> dist;
// Función para encontrar la distancia desde el nodo s hasta el nodo ix
void distance(int s, int ix) {
// Declarar una cola para almacenar el nodo y su distancia desde el nodo de
// inicio como un par
queue<pair<int, int>> q;
q.push({s, 0});
dist[ix][s] = 0;
while (!q.empty()) {
pair<int, int> p = q.front();
q.pop();
for (int n : mp[p.first]) {
if (dist[ix][n] != -1) { continue; }
dist[ix][n] = p.second + 1;
q.push({n, dist[ix][n]});
}
}
}
int main() {
int B, E, P, N, M;
cin >> B >> E >> P >> N >> M;
dist.assign(4, vector<int>(N + 1, -1));
for (int i = 0; i < M; i++) {
int u, v;
cin >> u >> v;
mp[--u].push_back(--v);
mp[v].push_back(u);
}
distance(0, 0); // encontrar la distancia de cada nodo desde el nodo 0
distance(1, 1); // encontrar la distancia de cada nodo desde el nodo 1
distance(N - 1, 2); // encontrar la distancia de cada nodo desde el nodo N - 1
int min_energy = INT32_MAX;
for (int i = 0; i < N; i++) {
int energy = dist[0][i] * B + dist[1][i] * E + dist[2][i] * min(B + E, P);
min_energy = min(min_energy, energy);
}
cout << min_energy << endl;
}import java.io.*;
import java.util.*;
public class Piggyback {
static int B, E, P, N, M, A = Integer.MAX_VALUE;
static List<Integer>[] adj;
static int[][] dist;
public static void main(String[] args) throws Exception {
Kattio io = new Kattio("piggyback");
B = io.nextInt();
E = io.nextInt();
P = io.nextInt();
N = io.nextInt();
M = io.nextInt();
adj = new List[N];
dist = new int[3][N];
for (int i = 0; i < 3; i++) { Arrays.fill(dist[i], -1); }
for (int i = 0; i < N; i++) { adj[i] = new ArrayList<>(); }
for (int i = 0; i < M; i++) {
int a = io.nextInt() - 1;
int b = io.nextInt() - 1;
adj[a].add(b);
adj[b].add(a);
}
bfs(0, 0);
bfs(1, 1);
bfs(N - 1, 2);
for (int i = 0; i < N; i++) {
A = Math.min(A, dist[0][i] * B + dist[1][i] * E +
dist[2][i] * Math.min(B + E, P));
}
io.println(A);
io.close();
}
private static void bfs(int s, int ix) {
Queue<Path> q = new LinkedList<>();
q.add(new Path(s, 0));
dist[ix][s] = 0;
while (!q.isEmpty()) {
Path curr = q.poll();
for (Integer n : adj[curr.i]) {
if (dist[ix][n] != -1) continue;
dist[ix][n] = curr.d + 1;
q.add(new Path(n, dist[ix][n]));
}
}
}
private static class Path {
int i, d;
public Path(int a, int b) {
i = a;
d = b;
}
}
// CodeSnip{Kattio}
}from collections import deque
def bfs(start, dist, adj):
dist[start] = 0
q = deque([start])
while q:
curr = q.popleft()
for neighbor in adj[curr]:
if dist[neighbor] == -1:
dist[neighbor] = dist[curr] + 1
q.append(neighbor)
def main():
with open("piggyback.in", "r") as fin:
B, E, P, n, m = map(int, fin.readline().split())
adj = [[] for _ in range(n)]
for _ in range(m):
a, b = map(int, fin.readline().split())
a -= 1
b -= 1
adj[a].append(b)
adj[b].append(a)
bessie_dist = [-1] * n
elsie_dist = [-1] * n
barn_dist = [-1] * n
# BFS desde cada punto de partida
bfs(0, bessie_dist, adj)
bfs(1, elsie_dist, adj)
bfs(n - 1, barn_dist, adj)
res = float("inf")
for i in range(n):
b_cost = bessie_dist[i] * B
e_cost = elsie_dist[i] * E
p_cost = barn_dist[i] * min(B + E, P) # P puede no ser más óptimo que B + E
res = min(res, b_cost + e_cost + p_cost)
print(res, file=open("piggyback.out", "w"))
if __name__ == "__main__":
main()