QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#47333 | #2232. Win Diesel | tovarisch | WA | 3ms | 13052kb | C++ | 3.0kb | 2022-09-08 06:12:54 | 2022-09-08 06:12:55 |
Judging History
answer
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <array>
using namespace std;
/* *
*
* Too many mind, no mind.
*
*
* */
using pii = pair <int, int>;
const int maxn = 2e5 + 10, LOG2N= 30;
int vis[maxn], dist[maxn], up[maxn][LOG2N];
vector <int> graph[maxn], g[maxn];
void dfs(int u, int p, int h){
dist[u] = h;
/*
* Binary lifting, we will jump in powers of 2.
* up[u][i] means we jump up from vertex u, 2^i positions.
* here we are calculating jumps for each power of 2.
*/
up[u][0] = p;
for(int i = 1; i <= LOG2N; i++)
up[u][i] = up[up[u][i - 1]][i - 1];
for(int v: g[u])
if(v != p) dfs(v, u, h + 1);
}
int lca(int u, int v){
// First both u, v should be at the same distance from the root (height).
if(dist[u] < dist[v]) swap(u, v);
int offset = dist[u] - dist[v];
for(int i = 0; i <= LOG2N; i++)
if(offset & (1 << i)) u = up[u][i];
// At this point u is at the same hight of v, if u == v it means v was the LCA of u.
if(u == v) return u;
// We want to lift up u and v to be childs of the lca, if jumping from
// u and v a distance 2^i ends in the same vertex (up[u][i] == up[v][i]) it
// means that it is the LCA or the vertex is above the LCA, then we do not jump that distance,
// we always want to be under the LCA in order to end at the childs of the LCA.
for(int i = LOG2N - 1; i >= 0; i--)
if(up[u][i] != up[v][i])
u = up[u][i], v = up[v][i];
return up[u][0];
}
int main() {
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int n, m; cin >> n >> m;
for (int i = 0; i < m; i++) {
int u, v; cin >> u >> v;
//cout << u << ' ' << v << endl;
graph[u].push_back(v);
graph[v].push_back(u);
}
vector <int> par(n, -1), vis(n, 0), nodes;
vector<int> q = {0};
vis[0] = 1;
while(!q.empty()){
vector <int> aux;
for (int& u : q) {
nodes.push_back(u);
for (int& v : graph[u]) {
if (vis[v]) continue;
par[v] = u;
vis[v] = 1;
aux.push_back(v);
}
}
sort(aux.begin(), aux.end());
q = aux;
}
//cout << "break" << endl;
for (int i = 1; i < n; i++) {
//cout << i << ' ' << par[i] << endl;
g[i].push_back(par[i]);
g[par[i]].push_back(i);
}
dfs(0, -1, 0);
long long ans = 0;
for (int i = 1; i < nodes.size(); i++) {
//cout << nodes[i] << ' ';
int u = nodes[i - 1], v = nodes[i];
int w = lca(u, v);
//cout << u << ' ' << v << ' ' << w << ' ' << dist[u] << ' ' << dist[v] << ' ' << dist[u] << endl;
ans += dist[u] + dist[v] - 2ll * dist[w];
}
cout << ans << endl;
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 13028kb
input:
6 9 3 4 3 0 3 5 3 2 4 1 4 2 1 0 0 5 5 2
output:
12
result:
ok single line: '12'
Test #2:
score: 0
Accepted
time: 1ms
memory: 13052kb
input:
7 10 6 1 6 4 6 3 1 2 1 4 1 3 2 4 2 5 4 0 3 0
output:
19
result:
ok single line: '19'
Test #3:
score: -100
Wrong Answer
time: 2ms
memory: 12964kb
input:
6 5 3 0 0 2 2 1 2 4 1 5
output:
15
result:
wrong answer 1st lines differ - expected: '11', found: '15'