(SPFA的SLF优化)AcWing342道路与航线

AcWing342道路与航线

思路:

看起来非常裸的spfa,然而精心构造的数据卡了。
就用到spfa的SLF优化,我们之前的spfa都是用队列实现的,每个数据都放到队尾。现在我们用双端队列,如果当前点的权值少于我们当前队头点的权值的话,那么我们就将这个节点插入到队头,否则我们插入到队尾。

代码:

#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
const int N=1e6+10;
const int mod=1e7+9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
struct edge
{
	int next,to,w;
}a[N];
int head[30000]={0},len=0,dis[30000]={0},vis[30000]={0};
void add(int u,int v,int w)
{
	a[++len]={head[u],v,w};
	head[u]=len;
}
int main()
{
	int t,r,p,s,i;
	scanf("%d%d%d%d",&t,&r,&p,&s);
	for(i=1;i<=r;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
		add(b,a,c);
	}
	for(i=1;i<=p;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
	}
	for(i=1;i<=t;i++)
		dis[i]=maxn;
	dis[s]=0;
	deque<int> q;
	q.push_back(s);
	vis[s]=1;
	while(!q.empty())
	{
		int pre=q.front();
		q.pop_front();
		vis[pre]=0;
		for(i=head[pre];i;i=a[i].next)
		{
			int v=a[i].to,w=a[i].w;
			if(dis[v]>dis[pre]+w)
			{
				dis[v]=dis[pre]+w;
				if(!vis[v])
				{
					vis[v]=1;
					if(q.size() && dis[v]<dis[q.front()])
						q.push_front(v);
					else
						q.push_back(v);
				}
			}
		}
	}
	for(i=1;i<=t;i++)
		if(dis[i]==maxn)
			printf("NO PATH\n");
		else
			printf("%d\n",dis[i]);
	return 0;
}

发布了78 篇原创文章 · 获赞 0 · 访问量 1391

猜你喜欢

转载自blog.csdn.net/Z7784562/article/details/104054926