社区讨论

最短路求助!!!

学术版参与者 4已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@mi7pf4lh
此快照首次捕获于
2025/11/21 01:27
4 个月前
此快照最后确认于
2025/11/21 01:27
4 个月前
查看原帖
大家好,我是一位刚学最短路的蒟蒻,然而我碰到了很神奇的问题,在做P4779时,我的手打堆优化过了样例,却只拿到了16分(1个点)
所以请某位巨佬帮忙......
CPP
#include<cstdio>
#include<cstring>
using namespace std;
const int N=5000010,M=500001,maxlongint=2147483647;
struct FarmerJohn
{
	int to,last,val;
}e[M];
int st[N],dis[N],bh[N],bz[N],rl[N],disa[N];
int tot=0,a,b,c,n,m,s,ln=0,sp,mn,mnl;
void add(int u,int v,int value)
{
	tot++;
	e[tot].val=value;
	e[tot].to=v;
	e[tot].last=st[u];
	st[u]=tot;
}
void pushe(int l,int lv)
{
	ln++;
	disa[ln]=l;
	rl[ln]=lv;
	bh[ln]=ln;
	for (int i=ln,j=i/2;j;i=j,j=i/2)
	{
		if (disa[j]>disa[i])
		{
			sp=disa[j];
			disa[j]=disa[i];
			disa[i]=sp;
			sp=bh[i];
			bh[i]=bh[j];
			bh[j]=sp;
			sp=rl[i];
			rl[i]=rl[j];
			rl[j]=sp;
		}
	}
}
void pope()
{
	mn=disa[1];
	mnl=rl[1];
	disa[1]=disa[ln];
	bh[1]=bh[ln];
	rl[1]=rl[ln];
	ln--;
	for (int i=1,j=i*2;j<=ln;i=j,j=i*2)
	{
		if (j+1<=ln && disa[j+1]<disa[j])
			j++;
		if (disa[i]>disa[j])
			break;
		else
		{
			sp=disa[i];
			disa[i]=disa[j];
			disa[j]=sp;
			sp=bh[i];
			bh[i]=bh[j];
			bh[j]=sp;
			sp=rl[i];
			rl[i]=rl[j];
			rl[j]=sp;
		}
	}
}
void update(int la,int lb)
{
	disa[lb]=la;
	for (int i=lb,j=i/2;j;i=j,j=i/2)
	{
		if (disa[j]<disa[i])
		{
			sp=disa[j];
			disa[j]=disa[i];
			disa[i]=sp;
			sp=bh[i];
			bh[i]=bh[j];
			bh[j]=sp;
			sp=rl[i];
			rl[i]=rl[j];
			rl[j]=sp;
		}
	}
}
void dij()
{
	int cnt=0;
	while (cnt<n-1)
	{
		pope();
		bz[mnl]=0;
		for (int i=st[mnl];i!=-1;i=e[i].last)
		{
			if (dis[e[i].to]>dis[mnl]+e[i].val)
			{
				dis[e[i].to]=dis[mnl]+e[i].val;
				if (bz[e[i].to]==0)
				{
					bz[e[i].to]=1;
					pushe(dis[e[i].to],e[i].to);
				}
				else
				{
					update(dis[e[i].to],bh[e[i].to]);	
				}
			}
		}
		mnl=0;
		mn=0;
		cnt++;
	}
}
int main()
{
	scanf("%d %d %d",&n,&m,&s);
	memset(st,-1,sizeof st);
	memset(bz,0,sizeof bz);
	memset(disa,0,sizeof disa);
	for (int i=1;i<=n;i++)
		dis[i]=maxlongint;
	for (int i=1;i<=m;i++)
	{
		scanf("%d %d %d",&a,&b,&c);
		add(a,b,c);
	}
	dis[s]=0;
	bz[s]=1;
	pushe(dis[s],s);
	dij();
	for (int i=1;i<=n;i++)
		printf("%d ",dis[i]);
	return 0;
}
谢谢帮忙,我会有红(jing)包(shen)奖励

回复

5 条回复,欢迎继续交流。

正在加载回复...