P1266 速度限制 (最短路,图论)

题目链接


Solution

在最短路转移的时候在队列或者堆中记录状态为 \(f[u][v]\) 代表上一个节点为 \(u\) ,速度为 \(v\) .
然后按部就班转移即可...

Code

#include<bits/stdc++.h>
#define ff double
using namespace std;

struct sj{int v,to,next;ff w;}a[10008];
struct node{int u,v;};
int head[508],size;
int n,m,d,v[208][508];
ff dis[208][508];
node pre[208][508];

void add(int x,int y,int v,ff w)
{
    a[++size].to=y;
    a[size].next=head[x];
    head[x]=size;
    a[size].w=w;
    a[size].v=v;
}

void spfa()
{
	 queue<node>q;
	 q.push((node){0,70});
	 dis[0][70]=0;v[0][70]=1;
	 while(q.empty()!=1)
	 {
			node x=q.front();
			q.pop(); int u=x.u,sp=x.v;
			for(int i=head[u];i;i=a[i].next)
			{
				int tp=0,tt=a[i].to;
				tp=(a[i].v?a[i].v:sp);
			    if(tp)
				if(dis[tt][tp]>dis[u][sp]+(a[i].w*1.0/tp*1.0))
						{
								pre[tt][tp]=x;
								dis[tt][tp]=dis[u][sp]+(a[i].w*1.0/tp*1.0);
								if(!v[tt][tp])
								{
									q.push((node){tt,tp});
									v[tt][tp]=1;
								}
						}
			}
      v[u][sp]=0;
	  }
}

void print(int x,int speed)
{
    if(x!=0)
    print(pre[x][speed].u,pre[x][speed].v);
    cout<<x<<' '; return;
}

int main()
{
    scanf("%d%d%d",&n,&m,&d);
    for(int i=1;i<=n;i++)
    for(int j=0;j<=500;j++)
    dis[i][j]=19260817;
    for(int i=1;i<=m;i++)
    {
        int x,y,v; ff w;
        scanf("%d%d%d%lf",&x,&y,&v,&w);
        add(x,y,v,w);
    }
    spfa();
    ff now=192608173;
    int ans;
    for(int i=1;i<=500;i++)
    {
        if(dis[d][i]<now)
        now=dis[d][i],ans=i;
    }
    print(d,ans);
}

posted @ 2018-08-27 20:01  Kevin_naticl  阅读(241)  评论(0编辑  收藏  举报