QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#47333#2232. Win DieseltovarischWA 3ms13052kbC++3.0kb2022-09-08 06:12:542022-09-08 06:12:55

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-09-08 06:12:55]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:13052kb
  • [2022-09-08 06:12:54]
  • 提交

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'