思路:树剖+kruskal,TLE*2+WA*2
查看原帖
思路:树剖+kruskal,TLE*2+WA*2
326254
LonginusMonkey楼主2023/8/15 21:24

求助啊,TLE2+WA2,思想为重剖,处理次大最大。

为什么会WA2点,TLE2点,讨论区从未有这种情况,求助!

#include<bits/stdc++.h>
#define N 300100
#define int long long
using namespace std;
int n, m;
int w_new[N];
struct node{
	int u, v, w;
}edge[N];
struct node2{
	int to, w;
};
struct node3{
	int nowmax, nextmax;
}tree[N<<3];
vector<node2> vec[N];
bool cmp(node x, node y) {
	return x.w < y.w;
}
int is[N], father[N];
int find(int index) {
	if(father[index] == index) {
		return index;
	}
	return father[index] = find(father[index]);
}
int size[N], son[N], wson[N], new_w[N], top[N], dfn[N], ti, fa[N], depth[N];
void dfs1(int index, int back) {
	size[index] = 1;
	for(int i=0; i<vec[index].size(); ++i) {
		if(vec[index][i].to == back) continue;
		dfs1(vec[index][i].to, index);
		size[index] += size[vec[index][i].to];
		if(son[index] == 0 || size[vec[index][i].to] > size[son[index]]) {
			son[index] = vec[index][i].to; wson[index] = vec[index][i].w;
		}
	}
}
void dfs2(int index, int back, int tp) {
	top[index] = tp;fa[index] = back; dfn[index]=++ti;
	depth[index] = depth[back]+1;
	if(son[index]) {
		dfs2(son[index], index, tp);
		w_new[dfn[son[index]]] = wson[index];
	}
	for(int i=0; i<vec[index].size(); ++i) {
		if(vec[index][i].to == back || vec[index][i].to == son[index]) continue;
		dfs2(vec[index][i].to, index, vec[index][i].to);
		w_new[dfn[vec[index][i].to]] = vec[index][i].w;
	}
}
node3 update(node3 y, node3 z) {
	node3 x;
	node3 a=y, b=z;
	if(a.nowmax > b.nowmax) {
		x.nowmax = a.nowmax;
		x.nextmax = max(b.nowmax, a.nextmax);
		return x;
	} 
	if(a.nowmax < b.nowmax) {
		x.nowmax = b.nowmax;
		x.nextmax = max(a.nowmax, b.nextmax);
		return x;
	}
	if(a.nowmax == b.nowmax) {
		x.nowmax = a.nowmax;
		x.nextmax = max(a.nextmax, b.nextmax);
		return x;
	}
}
void build(int l, int r, int index) {
	if(l==r) {
		tree[index].nowmax = w_new[l];
		tree[index].nextmax = 0;
		return;
	}
	int mid = l + r >> 1;
	build(l, mid, index*2); build(mid+1, r, index*2+1);
	tree[index] = update(tree[index*2], tree[index*2+1]);
}
node3 ask(int l, int r, int index, int left, int right) {
	node3 temp; temp.nextmax = 0; temp.nowmax = 0;
	if(left > right) {
		return temp;
	}
	if(l > right || r < left) return temp;
	if(l>=left && r<=right) {
		temp.nextmax = tree[index].nextmax;
		temp.nowmax = tree[index].nowmax;
		return temp;
	}
	int mid = l + r >> 1;
	node3 tempx = ask(l, mid, index*2, left, right), tempy = ask(mid+1, r, index*2+1, left, right);
	temp = update(tempx, tempy);
	return temp;
}
node3 Ask(int l, int r) {
	node3 ans; ans.nextmax = 0; ans.nowmax = 0;
	while(top[l] != top[r]) {
		if(depth[top[l]] > depth[top[r]]) {
			swap(l, r);
		}
		node3 temp = ask(1, n, 1, dfn[top[r]], dfn[r]);
		ans = update(temp, ans);
		r = father[top[r]];
	}
	if(depth[l] > depth[r]) {
		swap(l, r);
	}
	node3 temp = ask(1, n, 1, dfn[l]+1, dfn[r]);
	ans = update(temp, ans);
	return ans;
}
signed main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	for(int i=1; i<=n; ++i) father[i] = i; 
	for(int i=1; i<=m; ++i) {
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}
	sort(edge+1, edge+1+m, cmp);
	int tot = 0, sum = 0;
	for(int i=1; i<=n; ++i) {
		father[i] = i;
	}
	for(int i=1; i<=8*n; ++i) {
		tree[i].nextmax = tree[i].nowmax = 0;
	}
	for(int i=1; i<=m; ++i) {
		if(find(edge[i].u) != find(edge[i].v)) {
			is[i] = 1;father[find(edge[i].u)] = find(edge[i].v);
			vec[edge[i].u].push_back({edge[i].v, edge[i].w}); vec[edge[i].v].push_back({edge[i].u, edge[i].w});
			sum += edge[i].w; tot++;
		}
		if(tot == n-1) {
			break;
		}
	}
	dfs1(1, 0); dfs2(1, 0, 1); build(1, n, 1);
	int ans = 1e18;
	for(int i=1; i<=m; ++i) {
		if(is[i]) continue;
		node3 tempu = Ask(edge[i].u, edge[i].v);
		if(tempu.nowmax == edge[i].w) {
			if(tempu.nextmax == 0) {
				continue;
			} else {
				int temp = sum + edge[i].w - tempu.nextmax;
				if(temp<ans) ans=temp;
			}
		} else if(tempu.nowmax != 0){
			int temp = sum + edge[i].w - tempu.nowmax;
			if(temp<ans) ans=temp;
		}
	}
	if(ans == 1e18) {
		cout << "sto PinkieRabbit orz";
	} else {
		cout << ans;
	}
	return 0;
}
2023/8/15 21:24
加载中...