#include "citymapping.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ask(int i, int j)
{
return get_distance(i + 1, j + 1);
}
void find_roads(int n, int q, int e_a[], int e_b[], int e_w[])
{
vector<ll> dist0(n, 0);
vector<int> ord;
for (int i = 1; i < n; i++)
{
dist0[i] = ask(0, i);
ord.push_back(i);
}
sort(ord.begin(), ord.end(), [&] (int i, int j) {return dist0[i] < dist0[j];});
vector<int> deja = {0};
vector<vector<int>> g(n);
vector<int> sub(n), big(n), u(n), par(n);
int top = 0;
auto add_edge = [&] (int a, int b)
{
/// cout << " add_edge : " << a << " " << b << "\n";
e_a[top] = a + 1;
e_b[top] = b + 1;
e_w[top] = dist0[b] - dist0[a];
g[a].push_back(b);
top++;
};
function<void(int)> dfs = [&] (int a)
{
sub[a] = 1;
if (g[a].empty())
{
u[a] = a;
return;
}
assert(!g[a].empty());
big[a] = g[a][0];
for (auto &b : g[a])
{
dfs(b);
par[b] = a;
sub[a] += sub[b];
if (sub[b] > sub[big[a]])
{
big[a] = b;
}
}
u[a] = u[big[a]];
};
function<void(int, int)> locate = [&] (int root, int new_vertex)
{
if (sub[root] == 1)
{
add_edge(root, new_vertex);
return;
}
assert(!g[root].empty());
int b = u[root];
assert(b != root);
ll dist_b_v = ask(b, new_vertex);
ll dist_b_r = dist0[b] - dist0[root];
ll dist_v_r = dist0[new_vertex] - dist0[root];
/**
x + y = dist_b_r
z + y = dist_b_v
x + z = dist_v_r
z = sum - dist_b_r
x = sum - dist_b_v
y - sum - dist_v_r
**/
ll sum_dub = (dist_b_v + dist_b_r + dist_v_r);
assert(sum_dub % 2 == 0);
ll sum = sum_dub / 2;
ll z = sum - dist_b_r;
ll x = sum - dist_b_v;
ll y = sum - dist_v_r;
assert(x + y + z == sum);
assert(0 <= x);
assert(0 <= y);
assert(0 <= z);
assert(x + y == dist_b_r);
assert(z + y == dist_b_v);
assert(x + z == dist_v_r);
int fix_inainte = -1;
/// scapa de astea!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/// assert(x + y == ask(root, b));
/// assert(x + z == ask(root, new_vertex));
/// assert(z + y == ask(b, new_vertex));
/// scapa de astea!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (y == 0)
{
add_edge(b, new_vertex);
return;
}
// cout << "x = " << x << "\n";
// cout << "y = " << y << "\n";
// cout << "z = " << z << "\n";
while (y > 0)
{
assert(b != root);
y -= (dist0[b] - dist0[par[b]]);
fix_inainte = b;
b = par[b];
}
assert(y == 0);
int mid_point = b;
if (z == 0)
{
add_edge(mid_point, new_vertex);
return;
}
assert(z > 0);
///cout << " = " << fix_inainte << " " << b << " " << root << "\n";
assert(0 <= fix_inainte && fix_inainte < n);
assert(par[fix_inainte] == b);
if ((int) g[mid_point].size() == 1)
{
add_edge(mid_point, new_vertex);
return;
}
assert((int) g[mid_point].size() == 2 || (int) g[mid_point].size() == 3);
vector<int> oth;
for (auto &vecin : g[mid_point])
{
if (vecin == fix_inainte)
{
continue;
}
oth.push_back(vecin);
}
assert((int) oth.size() == 1 || (int) oth.size() == 2);
assert((int) oth.size() == (int) g[mid_point].size() - 1);
if ((int) oth.size() == 1)
{
locate(oth[0], new_vertex);
return;
}
assert((int) oth.size() == 2);
if (ask(oth[0], new_vertex) < ask(oth[1], new_vertex))
{
locate(oth[0], new_vertex);
}
else
{
locate(oth[1], new_vertex);
}
};
int nd = 0;
for (auto &vertex : ord)
{
/// cout << " \t\t\t\t\t vertex = " << vertex << "\n";
dfs(0);
locate(0, vertex);
nd++;
assert(nd == top);
/// cout << " \t\t\t\t\t\t\t\t\t" << e_a[nd - 1] << " " << e_b[nd - 1] << " " << e_w[nd - 1] << "\n";
continue;
return;
for (int p = (int) deja.size() - 1; p >= 0; p--)
{
int oth = deja[p];
if (ask(oth, vertex) + dist0[oth] == dist0[vertex])
{
add_edge(oth, vertex);
break;
}
}
deja.push_back(vertex);
}
if (0)
{
for (int i = 0; i < top; i++)
{
cout << " : " << e_a[i] << " " << e_b[i] << " " << e_w[i] << "\n";
}
}
assert(top == n - 1);
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
18 ms |
516 KB |
Correct: 2693 out of 500000 queries used. |
2 |
Correct |
15 ms |
468 KB |
Correct: 2161 out of 500000 queries used. |
3 |
Correct |
16 ms |
500 KB |
Correct: 4172 out of 500000 queries used. |
4 |
Incorrect |
15 ms |
508 KB |
Reported list of edges differ from actual. |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
18 ms |
516 KB |
Correct: 2693 out of 500000 queries used. |
2 |
Correct |
15 ms |
468 KB |
Correct: 2161 out of 500000 queries used. |
3 |
Correct |
16 ms |
500 KB |
Correct: 4172 out of 500000 queries used. |
4 |
Incorrect |
15 ms |
508 KB |
Reported list of edges differ from actual. |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
16 ms |
468 KB |
Correct: 2081 out of 12000 queries used. |
2 |
Correct |
18 ms |
468 KB |
Correct: 2319 out of 12000 queries used. |
3 |
Correct |
19 ms |
468 KB |
Correct: 2457 out of 12000 queries used. |
4 |
Correct |
16 ms |
468 KB |
Correct: 2464 out of 12000 queries used. |
5 |
Correct |
17 ms |
556 KB |
Correct: 2231 out of 12000 queries used. |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
16 ms |
468 KB |
Correct: 2081 out of 12000 queries used. |
2 |
Correct |
18 ms |
468 KB |
Correct: 2319 out of 12000 queries used. |
3 |
Correct |
19 ms |
468 KB |
Correct: 2457 out of 12000 queries used. |
4 |
Correct |
16 ms |
468 KB |
Correct: 2464 out of 12000 queries used. |
5 |
Correct |
17 ms |
556 KB |
Correct: 2231 out of 12000 queries used. |
6 |
Correct |
17 ms |
532 KB |
Correct: 2472 out of 12000 queries used. |
7 |
Correct |
17 ms |
568 KB |
Correct: 2381 out of 12000 queries used. |
8 |
Correct |
16 ms |
468 KB |
Correct: 2206 out of 12000 queries used. |
9 |
Correct |
19 ms |
556 KB |
Correct: 2234 out of 12000 queries used. |
10 |
Correct |
19 ms |
568 KB |
Correct: 2301 out of 12000 queries used. |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
18 ms |
516 KB |
Correct: 2693 out of 500000 queries used. |
2 |
Correct |
15 ms |
468 KB |
Correct: 2161 out of 500000 queries used. |
3 |
Correct |
16 ms |
500 KB |
Correct: 4172 out of 500000 queries used. |
4 |
Incorrect |
15 ms |
508 KB |
Reported list of edges differ from actual. |
5 |
Halted |
0 ms |
0 KB |
- |