10ptsPrim+堆优化求助
查看原帖
10ptsPrim+堆优化求助
473188
NaHCO3_tht楼主2021/7/21 18:09
#include <bits/stdc++.h>
#define next nn
#define ll long long 

using namespace std;
const ll inf = 0x3f3f3f3f,MAXM = 4e5+10,MAXN = 5e3+10;
inline ll read(){
	ll x = 0,f = 1; char ch = getchar();
	while(!isdigit(ch)){if(ch == '-') f = -1; ch = getchar();}
	while(isdigit(ch)){x = x*10+ch-48; ch = getchar();}
	return x*f;
}
inline void write(ll ch){
	if(ch < 0){putchar('-'); write(-ch);}
	if(ch > 9) write(ch/10);
	putchar(ch%10+48);
}
ll dis[MAXN],book[MAXN],n,m;
ll h[MAXN],pos[MAXN],size;
ll u[MAXM],v[MAXM],w[MAXM],first[MAXN],next[MAXM];
ll cnt,sum;

//手写堆应用
inline void swp(ll x,ll y){
	ll t;
	t = h[x]; h[x] = h[y]; h[y] = t;
	t = pos[h[x]]; pos[h[x]] = pos[h[y]]; pos[h[y]] = t;
}
inline void shiftdown(ll i){
	ll t; bool flag = 0;
	while(i<<1 <= size && !flag){
		if(dis[h[i]] > dis[h[i<<1]]) t = i<<1;
		else t = i;
		if((i<<1)+1 <= size){
			if(dis[t] > dis[h[(i<<1)+1]])
				t = (i<<1)+1;
		}
		if(t != i){
			swp(t,i);
			i = t;
		}else{
			flag = 1;
		}
	}
}
inline void shiftup(int i){
	bool flag = 0;
	if(i == 1) return ;
	while(i != 1 && flag == 0){
		if(dis[h[i]] < dis[h[i>>1]])
			swp(i,i>>1);
		else
			flag = 1;
		i>>=1;
	}
}
inline ll pop(){
	ll t;
	t = h[1];
	pos[t] = 0;
	h[1] = h[size--];
	pos[h[1]] = 1;
	shiftdown(1);
	return t; 
}
//完成辣

int main(){
	n = read(); m = read();
	for(register int i = 1;i <= m;i++){
		u[i] = read(); v[i] = read(); w[i] = read();
	}
	
	for(register int i = m+1;i <= m<<1;i++){
		u[i] = v[i-m];
		v[i] = u[i-m];
		w[i] = w[i-m];
	}
	memset(first,-1,sizeof(first));
	for(register int i = 1;i <= m<<1;i++){
		next[i] = first[u[i]];
		first[u[i]] = i;
	}
	//prim核心
	book[1] = 1;cnt++;
	memset(dis,inf,sizeof(dis));
	dis[1] = 0;
	ll k = first[1];
	while(k != -1){
		dis[v[k]] = w[k];
		k = next[k];
	}
	size = n;
	for(register int i = 1;i <= size;i++){h[i] = i; pos[i] = i;}
	for(register int i = size>>1;i >= 1;i--){shiftdown(i);}
	pop();
	while(cnt < n){
		int j = pop();
		book[j] = 1; cnt++; sum+=dis[j];
		
		k = first[j];
		while(k != -1){
			if(!book[v[k]] && dis[v[k]] > w[k]){
				dis[v[k]] = w[k];
				shiftup(pos[v[k]]);
			}
			k = next[k];
		}
	}
	write(sum);
	return 0;
}
2021/7/21 18:09
加载中...