QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#235872#5548. Increase the Toll FeesdmmmWA 3ms79660kbC++172.6kb2023-11-03 11:41:552023-11-03 11:41:55

Judging History

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

  • [2023-11-03 11:41:55]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:79660kb
  • [2023-11-03 11:41:55]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int MAXN = 2e5 + 6.9;
const int L = 20;
const int INF = 1e18;
struct edge {
	int u, v, w;
	bool operator < (const edge& oth) const {
		return w < oth.w;
	}
};
int n, m;
vector<edge> e;
vector<int> mst, mst2;
vector<int> adj[MAXN];
vector<int> adj2[MAXN];
int par[L][MAXN];
int maxi[L][MAXN];
int tin[MAXN], tout[MAXN];
int h[MAXN];
int timer;
int root[MAXN];
int Find(int u) {
	return root[u] < 0 ? u : root[u] = Find(root[u]);
}
int Union(int u, int v) {
	u = Find(u); v = Find(v);
	if (u == v) return 0;
	if (root[u] > root[v]) swap(u, v);
	root[u] += root[v];
	root[v] = u;
	return 1;
}
vector<int> FindMST(vector<int>& ban) {
	for (int i = 1; i <= n; i++) root[i] = -1;
	vector<int> mst;
	for (int i = 0, j = 0; i < m; i++) {
		if (j >= ban.size() || i != ban[j]) {
			int u = e[i].u;
			int v = e[i].v;
			if (Union(u, v)) mst.push_back(i);
		}
		else j++;
	}
	return mst;
}
void dfs(int u, int p, int w) {
	tin[u] = ++timer;
	h[u] = h[p] + 1;
	par[0][u] = p;
	maxi[0][u] = w;
	for (int i = 1; i < L; i++) {
		par[i][u] = par[i - 1][par[i - 1][u]];
		maxi[i][u] = max(maxi[i - 1][u], maxi[i - 1][par[i - 1][u]]);
	}
	for (int& id: adj[u]) {
		int v = e[id].u + e[id].v - u;
		if (v == p) continue;
		dfs(v, u, e[id].w);
	}
	tout[u] = timer;
}
int is_ancestor(int u, int v) {
	return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int lca(int u, int v) {
	if (is_ancestor(u, v)) return u;
	if (is_ancestor(v, u)) return v;
	for (int i = L - 1; i >= 0; i--) {
		if (!is_ancestor(par[i][u], v)) u = par[i][u];
	}
	return par[0][u];
}
int getmax(int u, int p) {
	int ans = 0;
	if (u == p) return ans;
	for (int i = L - 1; i >= 0; i--) {
		if (!is_ancestor(par[i][u], u)) {
			ans = max(ans, maxi[i][u]);
			u = par[i][u];
		}
	}
	ans = max(ans, maxi[0][u]);
	return ans;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int u, v, w; cin >> u >> v >> w;
		e.push_back({u, v, w});
	}
	sort(e.begin(), e.end());
	mst = FindMST(mst);
	mst2 = FindMST(mst);
	if (mst2.size() < n - 1) {
		cout << -1;
		return 0;
	}
	for (int i: mst2) {
		int u = e[i].u;
		int v = e[i].v;
		adj[u].push_back(i);
		adj[v].push_back(i);
		// cout << e[i].u << ' ' << e[i].v << ' ' << e[i].w << '\n';
	}
	dfs(1, 1, 0);
	int ans = 0;
	for (int& i: mst) {
		int u = e[i].u;
		int v = e[i].v;
		int p = lca(u, v);
		int need = max(getmax(u, p), getmax(v, p)) + 1;
		// cout << u << ' ' << v << ' ' << need << ' ' << e[i].w << '\n';
		ans += need - e[i].w;
	}
	cout << ans;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 79448kb

input:

4 6
1 2 2
1 3 5
1 4 5
2 3 3
2 4 5
3 4 4

output:

9

result:

ok single line: '9'

Test #2:

score: 0
Accepted
time: 0ms
memory: 13944kb

input:

3 4
1 2 3
2 3 4
1 3 5
1 3 10

output:

-1

result:

ok single line: '-1'

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 79660kb

input:

5 10
1 2 14
1 3 14
1 4 9
1 5 15
2 3 8
2 3 10
2 4 13
3 4 8
4 5 10
4 5 15

output:

20

result:

wrong answer 1st lines differ - expected: '21', found: '20'