2019 ICPC Asia Yinchuan Regional H. Delivery Route

题目

大意:给你x条双向边和y条单向边,问你这个点中每个点到s点的最小距离(注意:单向边可能为负,所以要用spfa)但是裸的spfa又会tle,这时就要用slf优化
这是我的spfa优化的代码,但是用了容器,还是会tle

#include
#include
#include
#include 
#include
#define maxn 25050
#define inf 0x3f3f3f3f

using namespace std;

vector<pair<int,int> >edge[maxn];
int dis[maxn],inqueue[maxn];
int n,x,y,s;

void spfa(int start){
	deque<int> q;
	q.push_back(start);
	dis[start]=0;
	inqueue[start]++;
	while(!q.empty()){
		int now=q.front();
		q.pop_front();
		inqueue[now]=0;
		for(int i=0;i<edge[now].size();i++){
			int v=edge[now][i].first;
			if(dis[v]>dis[now]+edge[now][i].second){
				dis[v]=dis[now]+edge[now][i].second;
				if(!q.empty()&&dis[v]>=dis[q.front()]){
					q.push_back(v);
				}else{
					q.push_front(v);
				}
				inqueue[v]=1;
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(dis[i]==inf){
			printf("NO PATH\n");
		}else{
			printf("%d\n",dis[i]);
		}
	}
}

int main(){
	memset(inqueue,0,sizeof(inqueue));
	memset(dis,inf,sizeof(dis));
	scanf("%d%d%d%d",&n,&x,&y,&s);
	for(int i=0;i<x;i++){
		int a,b,w;
		scanf("%d%d%d",&a,&b,&w);
		edge[a].push_back(make_pair(b,w));
		edge[b].push_back(make_pair(a,w));
	}
	for(int i=0;i<y;i++){
		int a,b,w;
		scanf("%d%d%d",&a,&b,&w);
		edge[a].push_back(make_pair(b,w));
	}
	spfa(s);
	return 0;
}

一开始我以为是调用vector容器时会用很长时间,后来用链式前向星表示,发现提交到计蒜客时一直显示段错误,后来我去看了别人的题解,发现是deque的问题,应该是deque不能太长,比如这题我试了应该要1e6次方。
代码如下:

#include
#include
#include
#include
#include
#define ll long long

using namespace std;

const int maxn = 1e6;

struct Edge{
	int to,next,w;
}edge[maxn];
int n,x,y,s,tot=1;
int head[maxn];
ll dis[maxn],val;
bool inq[maxn];

void add(int u,int v,int w){
	edge[tot].to=v;
	edge[tot].w=w;
	edge[tot].next=head[u];
	head[u]=tot++;
}
int q[2000100],l,r;
void spfa(){
	for(int i=1;i<=n;i++){
		dis[i]=1e15;
	}
	l=r=1e6;
	q[l]=s;
	dis[s]=0;
	inq[s]=true;
	while(l<=r){
		int now=q[l++];
		inq[now]=false;
		for(int i=head[now];i;i=edge[i].next){
			int v=edge[i].to;
			if(dis[v]>dis[now]+edge[i].w){
				dis[v]=dis[now]+edge[i].w;
				if(!inq[v]){
					if(l<=r&&dis[q[l]]+val>=dis[v]){
						q[--l]=v;
					}else{
						q[++r]=v;
					}
					inq[v]=true;
				}
			}
		} 
	}
	for(int i=1;i<=n;i++){
		if(dis[i]==1e15){
			printf("NO PATH\n");
		}else{
			printf("%lld\n",dis[i]);
		}
	}
}

int main(){
	memset(inq,false,sizeof(inq));
	scanf("%d%d%d%d",&n,&x,&y,&s);
	for(int i=1;i<=x;i++){
		int a,b,w;
		scanf("%d%d%d",&a,&b,&w);
		add(a,b,w);
		add(b,a,w);
		val+=2*w;
	}
	for(int i=1;i<=y;i++){
		int a,b,w;
		scanf("%d%d%d",&a,&b,&w);
		add(a,b,w);
		val+=w;
	}
	val=sqrt(val)/100;
	spfa();
	return 0;
}

你可能感兴趣的:(图论)