79分Prim堆优化求助
查看原帖
79分Prim堆优化求助
638942
Yzh20240706楼主2022/12/23 19:20

讨论区里的hack都能过

#include<stdio.h>
#define re register
using namespace std;
int dis[510],book[510];
int h[510],pos[510],size;
int a,b;
int k;
int u[1010],v[1010],w[1010],first1[1010],next1[1010];
int inf=99999999;
int count,sum;
int e[510][510];
int cnt;

void swap(int x,int y){
	int 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;
	return;
}

void siftdown(int i){
	int t,flag=0;
	while(i*2<=size&&flag==0){
		if(dis[h[i]]>dis[h[i*2]]){
			t=i*2;
		}
		else{
			t=i;
		}
		if(i*2+1<=size){
			if(dis[h[t]]>dis[h[i*2+1]]){
				t=i*2+1;
			}
		}
		if(t!=i){
			swap(t,i);
			i=t;
		}
		else{
			flag=1;
		}
	}
	return;
}

void siftup(int i){
	int flag=0;
	if(i==1){
		return;
	}
	while(i!=1&&flag==0){
		if(dis[h[i]]<dis[h[i/2]]){
			swap(i,i/2);
		}
		else{
			flag=1;
		}
		i=i/2;
	}
	return;
}

int pop(){
	int t;
	t=h[1];
	pos[t]=0;
	h[1]=h[size];
	pos[h[1]]=1;
    size--;
	siftdown(1);
	return t;
}

int main(){
	scanf("%d%d",&a,&b);
	for(re int i=1;i<=b;i++){
		for(re int j=1;j<=b;j++){
			scanf("%d",&e[i][j]);
			if(i==j){
				continue;
			}
			if(e[i][j]&&e[i][j]<=a){
				cnt++;
				u[cnt]=i;
				v[cnt]=j;
				w[cnt]=e[i][j];
			}
			else{
				cnt++;
				u[cnt]=i;
				v[cnt]=j;
				w[cnt]=a;
			}
		}
	}
	for(re int i=1;i<=b;i++){
		first1[i]=-1;
	}
	for(re int i=1;i<=cnt;i++){
		next1[i]=first1[u[i]];
		first1[u[i]]=i;
	}
	book[1]=1;
	count++;
	dis[1]=0;
	for(re int i=2;i<=b;i++){
		dis[i]=inf;
	}
	k=first1[1];
	while(k!=-1){
		dis[v[k]]=w[k];
		k=next1[k];
	}
	size=b;
	for(re int i=1;i<=size;i++){
		h[i]=i;
		pos[i]=i;
	}
	for(re int i=size/2;i>=1;i--){
		siftdown(i);
	}
	pop();
	int j;
	while(count<b){
		j=pop();
		book[j]=1;
		count++;
		sum=sum+dis[j];
		k=first1[j];
		while(k!=-1){
			if(book[v[k]]==0&&dis[v[k]]>w[k]){
				dis[v[k]]=w[k];
				siftup(pos[v[k]]);
			}
			k=next1[k];
		}
	}
	printf("%d",sum+a);
	return 0;
}
2022/12/23 19:20
加载中...