洛谷 P1266 速度限制 题解

题面

这道题可以理解为是一个分层图,也可以理解为是二维的SPFA

dis[i][j]表示到达i这个点速度为j的最短路

然后跑已经死了的SPFA就好了;

#include <bits/stdc++.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
int head[200010],cnt;
int inf=2e9+1;
class littlestar{
	public:
	int to;
	int nxt;
	int w;
	int speed;
	void add(int u,int v,int gg,int hh)
	{
		to=v;
		nxt=head[u];
		w=gg;
		speed=hh;
		head[u]=cnt;
	}
}star[200010];
int n,m,T;
class node1{
	public:
	int u,speed;
};
double dis[301][501];
int vis[301][501];
node1 pre[301][501];
void SPFA()
{
	queue<node1> qwq;
	qwq.push((node1){0,70});
	inc(i,0,n) inc(j,0,500) dis[i][j]=inf,pre[i][j].u=-1,pre[i][j].speed=-1;
	dis[0][70]=0;
	while(qwq.size()){
         node1 tmp=qwq.front();
         qwq.pop();
         vis[tmp.u][tmp.speed]=0;
         for(int i=head[tmp.u];i;i=star[i].nxt){
         	 int v=star[i].to;
         	 int now=star[i].speed;
         	 if(!now) now=tmp.speed;
         	 if(dis[tmp.u][tmp.speed]+(double)star[i].w/now<dis[v][now]){
         	 	dis[v][now]=dis[tmp.u][tmp.speed]+(double)star[i].w/now;
         	 	pre[v][now].u=tmp.u;
         	 	pre[v][now].speed=tmp.speed;
         	 	if(!vis[v][now]){
         	 		vis[v][now]=1;
         	 		qwq.push((node1){v,now});
         	 	}
         	 }
         }
	}
}
int ans[3000];
int main()
{
	
	cin>>n>>m>>T;
	inc(i,1,m){
		int a,b,c,d;
		scanf("%d%d%d%d",&a,&b,&c,&d);
		star[++cnt].add(a,b,d,c);
	}
	SPFA();
	double minn=999999999.9,id=0;
	inc(i,0,500){
		if(minn>dis[T][i]){
			minn=dis[T][i];id=i;
		}
	}
	int now=T,now2=id,cnt=0;
	while(now!=-1){
		ans[++cnt]=now;
		int tmp=now2;
		now2=pre[now][now2].speed;
		now=pre[now][tmp].u;
	}
	for(int i=cnt;i>=1;i--){
		cout<<ans[i]<<" ";
	}
}
/*
6 15 1

0 1 25 68

0 2 30 50

0 5 0 101

1 2 70 77

1 3 35 42

2 0 0 22

2 1 40 86

2 3 0 23

2 4 45 40

3 1 64 14

3 5 0 23

4 1 95 8

5 1 0 84

5 2 90 64

5 3 36 40
*/

 

posted @ 2019-10-28 10:54  神之右大臣  阅读(213)  评论(0编辑  收藏  举报