#include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;
const int MAXN = 2005;
const int INF = 1e9;
struct Edge {
int to, weight;
};
vector<Edge> adj[MAXN];
int dist[MAXN], parent[MAXN], edge_weight[MAXN];
// Funkcja wysyłająca liczbę bit po bicie
void send_int(int value, int bits) {
for (int i = 0; i < bits; i++) {
cout << "+ " << ((value >> i) & 1) << endl;
}
}
// Funkcja odbierająca liczbę bit po bicie
int read_int(int bits) {
int value = 0;
for (int i = 0; i < bits; i++) {
cout << "?" << endl;
int bit;
cin >> bit;
if (bit) value |= (1 << i);
}
return value;
}
void run_dijkstra(int n) {
for (int i = 1; i <= n; i++) dist[i] = INF;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
dist[1] = 0;
pq.push({0, 1});
while (!pq.empty()) {
int d = pq.top().first;
int u = pq.top().second;
pq.pop();
if (d > dist[u]) continue;
for (auto& edge : adj[u]) {
if (dist[u] + edge.weight < dist[edge.to]) {
dist[edge.to] = dist[u] + edge.weight;
parent[edge.to] = u;
edge_weight[edge.to] = edge.weight;
pq.push({dist[edge.to], edge.to});
}
}
}
}
int main() {
// Szybsze I/O, ale przy interakcji endl i tak robi flush
ios_base::sync_with_stdio(false);
cin.tie(NULL);
string role;
if (!(cin >> role)) return 0;
int N, M;
cin >> N >> M;
for (int i = 0; i < M; i++) {
int u, v, c;
cin >> u >> v >> c;
adj[u].push_back({v, c});
adj[v].push_back({u, c});
}
if (role == "Bajtek") {
// Bajtek znajduje swoje najlepsze krawędzie
run_dijkstra(N);
// Wysyła szkielet grafu Algosi (N-1 krawędzi)
for (int i = 2; i <= N; i++) {
send_int(parent[i], 11); // 11 bitów na numer miasta (do 2048)
send_int(edge_weight[i], 9); // 9 bitów na koszt (do 512)
}
}
else if (role == "Algosia") {
// Algosia odbiera krawędzie od Bajtka
for (int i = 2; i <= N; i++) {
int p = read_int(11);
int w = read_int(9);
if (p > 0) { // Jeśli miasto było osiągalne u Bajtka
adj[p].push_back({i, w});
adj[i].push_back({p, w});
}
}
// Algosia liczy ostateczną Dijkstrę na połączonych grafach
run_dijkstra(N);
// Wypisuje wynik
cout << "!";
for (int i = 1; i <= N; i++) {
cout << " " << dist[i];
}
cout << endl;
}
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #include <iostream> #include <vector> #include <string> #include <queue> using namespace std; const int MAXN = 2005; const int INF = 1e9; struct Edge { int to, weight; }; vector<Edge> adj[MAXN]; int dist[MAXN], parent[MAXN], edge_weight[MAXN]; // Funkcja wysyłająca liczbę bit po bicie void send_int(int value, int bits) { for (int i = 0; i < bits; i++) { cout << "+ " << ((value >> i) & 1) << endl; } } // Funkcja odbierająca liczbę bit po bicie int read_int(int bits) { int value = 0; for (int i = 0; i < bits; i++) { cout << "?" << endl; int bit; cin >> bit; if (bit) value |= (1 << i); } return value; } void run_dijkstra(int n) { for (int i = 1; i <= n; i++) dist[i] = INF; priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; dist[1] = 0; pq.push({0, 1}); while (!pq.empty()) { int d = pq.top().first; int u = pq.top().second; pq.pop(); if (d > dist[u]) continue; for (auto& edge : adj[u]) { if (dist[u] + edge.weight < dist[edge.to]) { dist[edge.to] = dist[u] + edge.weight; parent[edge.to] = u; edge_weight[edge.to] = edge.weight; pq.push({dist[edge.to], edge.to}); } } } } int main() { // Szybsze I/O, ale przy interakcji endl i tak robi flush ios_base::sync_with_stdio(false); cin.tie(NULL); string role; if (!(cin >> role)) return 0; int N, M; cin >> N >> M; for (int i = 0; i < M; i++) { int u, v, c; cin >> u >> v >> c; adj[u].push_back({v, c}); adj[v].push_back({u, c}); } if (role == "Bajtek") { // Bajtek znajduje swoje najlepsze krawędzie run_dijkstra(N); // Wysyła szkielet grafu Algosi (N-1 krawędzi) for (int i = 2; i <= N; i++) { send_int(parent[i], 11); // 11 bitów na numer miasta (do 2048) send_int(edge_weight[i], 9); // 9 bitów na koszt (do 512) } } else if (role == "Algosia") { // Algosia odbiera krawędzie od Bajtka for (int i = 2; i <= N; i++) { int p = read_int(11); int w = read_int(9); if (p > 0) { // Jeśli miasto było osiągalne u Bajtka adj[p].push_back({i, w}); adj[i].push_back({p, w}); } } // Algosia liczy ostateczną Dijkstrę na połączonych grafach run_dijkstra(N); // Wypisuje wynik cout << "!"; for (int i = 1; i <= N; i++) { cout << " " << dist[i]; } cout << endl; } return 0; } |
English