gym102331f 题解

题面


据说是减半报警器最早出现的地方。


先用一个堆维护所有被激活的边,然后用并查集维护联通块。

对于一条边,如果 \(w_u+w_v\ge s\),则有 \(\max(w_u,w_v)\ge\lceil\dfrac s2\rceil\)。对每个连通块维护一个堆记录一端在这个连通块里的边的阈值即可。


代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,w[300005],fa[300005];
struct edge{
	int u,v,w;
}e[300005];
int tog,las[300005],stp[300005];
struct node{
	int val,id,tim;
	bool operator<(const node &t)const{return val>t.val;}
};
priority_queue<node>q[300005];
int find(int x){
	if(fa[x]==x)return fa[x];
	else return fa[x]=find(fa[x]);
}
priority_queue<int,vector<int>,greater<int> >qq;
void Sol(node tmp){
	int p=tmp.id;
	if(find(e[p].u)==find(e[p].v))return;
	int sum=w[find(e[p].u)]+w[find(e[p].v)];
	if(stp[p]+e[p].w<=sum){
		qq.push(p);
		las[p]=-1;
		return;
	}
	e[p].w=stp[p]+e[p].w-sum;
	stp[p]=sum;
	int l=(e[p].w+1)/2;
	las[p]=++tog;
	q[find(e[p].u)].push(node({w[find(e[p].u)]+l,p,tog}));
	q[find(e[p].v)].push(node({w[find(e[p].v)]+l,p,tog}));
}
void ch(int id){
	while(!q[id].empty()&&q[id].top().val<=w[id]){
		node tmp=q[id].top();
		q[id].pop();
		if(tmp.tim!=las[tmp.id])continue;
		Sol(tmp);
	}
}
vector<int>ans;
signed main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++)scanf("%lld",&w[i]);
	for(int i=1;i<=m;i++){
		scanf("%lld%lld%lld",&e[i].u,&e[i].v,&e[i].w);
		if(w[e[i].u]+w[e[i].v]>=e[i].w)qq.push(i),las[i]=-1;
		else{
			las[i]=++tog;
			stp[i]=w[e[i].v]+w[e[i].u];
			e[i].w-=w[e[i].v]+w[e[i].u];
			int l=(e[i].w+1)/2;
			q[e[i].u].push(node({w[e[i].u]+l,i,tog}));
			q[e[i].v].push(node({w[e[i].v]+l,i,tog}));
		}
	}
	for(int i=1;i<=n;i++)fa[i]=i;
	while(!qq.empty()){
		int tmp=qq.top();
		qq.pop();
		int c=find(e[tmp].u),d=find(e[tmp].v);
		if(c==d)continue;
		ans.push_back(tmp);
		if(q[c].size()>q[d].size())swap(c,d);
		fa[c]=d;
		w[d]+=w[c];
		while(!q[c].empty()){
			node tmp=q[c].top();
			q[c].pop();
			if(tmp.tim!=las[tmp.id])continue;
			q[d].push(tmp);
		}
		ch(d);
	}
	printf("%lld\n",(int)ans.size());
	for(int x:ans)printf("%lld ",x);
	return 0;
}
posted @ 2024-12-03 19:54  Grisses  阅读(12)  评论(0)    收藏  举报
Document