QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#359715#6560. Broken Minimum Spanning Treenkamzabek#WA 1ms3620kbC++232.2kb2024-03-20 20:13:242024-03-20 20:13:25

Judging History

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

  • [2024-03-20 20:13:25]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3620kb
  • [2024-03-20 20:13:24]
  • 提交

answer

#include <bits/stdc++.h>

#define f first
#define s second
#define sz(s) (int)s.size()
#define pb push_back

using namespace std;

using vi = vector<int>;

const int N = (int)5e3 + 100;


int n, m, u[N], v[N], w[N];
int up[N][20];
pair<int, int> mx[N][20];
vector<int> g[N];
bool mst[N];
int tin[N], tout[N], timer;

bool is_par(int u, int v){
	return tin[u] <= tin[v] && tout[v] <= tout[u];
}

void dfs(int x, int par = 0, int ind = 0){
	up[x][0] = par;     
	mx[x][0] = {w[ind], ind};
	tin[x] = ++timer;

	for(int i = 1; i < 20; i++){
		up[x][i] = up[up[x][i - 1]][i - 1];
		mx[x][i] = max(mx[x][i - 1], mx[up[x][i - 1]][i - 1]);
	}
	for(auto i : g[x]){
		int to = (v[i] ^ u[i] ^ x); 
		if(to == par)
			continue;
		dfs(to, x, i);
	}
	tout[x] = timer;
}
int lca(int u, int v){
	if(is_par(u, v)) return u;
	if(is_par(v, u)) return v;
	for(int i = 19; i >= 0; i--)
		if(up[v][i] && !is_par(up[v][i], u))
			v = up[v][i];
	return up[v][0];
}

pair<int, int> get_max(int u, int v){
	int l = lca(u, v);
	pair<int, int> m = {0, 0};

	for(int i = 19; i >= 0; i--){
		if(up[u][i]){
			if(is_par(l, up[u][i])){
				u = up[u][i];
				m = max(m, mx[u][i]);
			}
		}
		if(up[v][i]){
			if(is_par(l, up[v][i])){
				v = up[v][i];
				m = max(m, mx[v][i]);
			}
		}	
	}
	return m;
}

main(){
	ios_base :: sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= m; i++){
		cin >> u[i] >> v[i] >> w[i];
		if(i < n) mst[i] = 1;
	}	
	
	vector<pair<int, int> > ans;
	while(1){
		for(int i = 1; i <= n; i++) g[i].clear();
		vector<int> ord;
		bool found = 0;
		for(int i = 1; i <= m; i++){
			if(mst[i]){
				g[u[i]].push_back(i);
				g[v[i]].push_back(i);
			}else{
				ord.push_back(i);
			}
		}

		dfs(1);
		
		sort(ord.begin(), ord.end(), [&](int i, int j){
			return w[i] < w[j];
		});
		for(int i : ord){
			int a = u[i], b = v[i];
			auto [val, j] = get_max(a, b);
			if(w[j] > w[i]){
				mst[i] = 1;
				mst[j] = 0;
				found = 1;
				ans.push_back({j, i});
				break;
			}
		}
		if(!found)
			break;
	}

	cout << sz(ans) << '\n';
	for(auto [x, y] : ans)
		cout << x << " " << y << "\n";
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3592kb

input:

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

output:

1
1 4

result:

ok correct!

Test #2:

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

input:

6 8
1 2 10
2 3 10
3 4 10
4 5 10
5 6 10
6 1 10
1 3 1
4 6 1

output:

1
3 8

result:

wrong answer not a spanning tree after swap 1