SSL 2550 重要人物#spfa#

本文主要分析SSL 2550问题,重点探讨了SPFA(Shortest Path Faster Algorithm)最短路径算法在解决该问题中的应用,并提供了相应的代码实现。
摘要由CSDN通过智能技术生成

比赛


这里写图片描述


分析

spfa


代码

#include <cstdio>
#include <cctype>
using namespace std;
struct node{int x,y,w,next,l,r;}e[20001];
int n,m,ls[1001],time[1001]; bool v[1001];
void spfa(int st){
	int list[1001],head=0,tail=1; list[1]=st; v[st]=1;
	do{
		head=head%n+1;
		int t=ls[list[head]];
		while (t){
			if (time[e[t].y]>time[e[t].x]+e[t].w){
			if (time[e[t].x]<e[t].l||time[e[t].x]>=e[t].r)//可以走
			time[e[t].y]=time[e[t].x]+e[t].w;
			else if (time[e[t].y]>time[e[t].x]+e[t].w+e[t].r-time[e[t].x])//等待
			time[e[t].y]=time[e[t].x]+e[t].w+e[t].r-time[e[t].x];
			if (!v[e[t].y]){
				v[e[t].y]=1;
				tail=tail%n+1;
				list[tail]=e[t].y;
			}
			}
			t=e[t].next;
		}
		v[list[head]]=0;
	}while (head!=tail);
}
int in(){
	int ans=0; char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans;
}
void add(int x,int y,int w){
	e[++m].x=x; e[m].y=y; e[m].w=w; e[m].next=ls[e[m].x]; ls[e[m].x]=m;
}
int main(){
	int st,en,stt,g,o,c[1001];
	n=in(); o=in(); st=in(); en=in(); stt=in(); stt++; g=in();
	for (int i=1;i<=g;i++) c[i]=in();
	while (o--){
		int x=in(),y=in(),w=in();
		add(x,y,w); add(y,x,w);
	}
	int s=1;
	for (int i=1;i<g;i++){//入边处理重要人物走的时间
		int t=ls[c[i]];
		while (t){
			if (e[t].y==c[i+1]) e[t].l=s,e[t].r=s+e[t].w,s+=e[t].w;
			t=e[t].next;
		}
	}
	for (int i=g;i>1;i--){//出边处理
		int t=ls[c[i]];
		while (t){
			if (e[t].y==c[i-1]) e[t].l=s-e[t].w,e[t].r=s,s-=e[t].w;
		    t=e[t].next;
		}
	}
	for (int i=1;i<=n;i++) time[i]=2147483647; time[st]=stt;
	spfa(st);
	printf("%d",time[en]-stt);
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值