洛谷P1266 速度限制
题意很好理解,就是给你一个图,\(n\) 个点,\(m\) 条边,每条边包含长度 \(l\),和 速度 \(v\),求从 \(0\) 到 \(d\) 最短花多少时间,如果 \(v=0\) 那么速度为到这条边的起点时的速度,也就是保持原速不变。
我用的邻接矩阵,用结构体 \(G_{i,j}\) 存 \(i\) 到 \(j\) 是否有边 \((flag)\)、距离 \((l)\)、速度 \((v)\)。
因为不同的速度会导致不同的结果,所以我们要把速度也标记下来。
用 \(dis_{i,j}\) 表示从 \(0\) 到 \(i\) 并且到 \(i\) 时速度为 \(j\) 的最短时间,我们用 \(dijkstra+\)堆优化 求出 \(dis\),然后在 \(dis_{d,i}(0≤i≤500)\) 中找到最小的 \(dis\),把速度存下来。
最后递归输出。用结构体数组 \(pre_{i,j}\) 存 \(dis_{i,j}\) 是由什么转移过来的。
输出的时候,就一直向前查找,直到前一个点为 \(-1\) 再输出并回溯。
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#define N 200
#define V 510
#define INF 0x3f3f3f3f
using namespace std;
int n,m,d;
struct point
{
int flag,v,l; //flag:是否有边,v:速度,l:长度
}G[N][N];
struct node //优先队列的类型
{
int u,v; //u:节点编号,v:到u时的速度
double t; //已经用了多长时间
node(int _u=0,int _v=0,double _t=0)
{
u=_u;
v=_v;
t=_t;
}
const bool operator < (const node b) const //因为我写的大根堆,所以要反过来
{
return t==b.t?v<b.v:t>b.t; //时间越小越好,如果相等,速度越大越好
}
};
struct PRE
{
int u,v; //前一个点的编号和速度
}pre[N][V];
double dis[N][V];
int vis[N][V];
priority_queue <node> que;
void dijkstra()
{
memset(dis,0x7f,sizeof(dis));
memset(pre,-1,sizeof(pre));
dis[0][70]=0;
que.push(node(0,70,dis[0][70]));
while(!que.empty())
{
node p=que.top();
que.pop();
int i=p.u,j=p.v;
if(vis[i][j]) continue;
vis[i][j]=1;
for(int k=0; k<n; k++)
{
if(G[i][k].flag)
{
if(!G[i][k].v)
{
if(dis[i][j]+(double)(1.0*G[i][k].l/j)<dis[k][j])
{
dis[k][j]=dis[i][j]+(double)(1.0*G[i][k].l/j);
que.push(node(k,j,dis[k][j]));
pre[k][j].u=i;
pre[k][j].v=j;
}
}
else
{
int v=G[i][k].v;
if(dis[i][j]+(double)(1.0*G[i][k].l/v)<dis[k][v])
{
dis[k][v]=dis[i][j]+(double)(1.0*G[i][k].l/v);
que.push(node(k,v,dis[k][v]));
pre[k][v].u=i;
pre[k][v].v=j;
}
}
}
}
}
return;
}
void print(int u,int v)
{
if(pre[u][v].u!=-1) print(pre[u][v].u,pre[u][v].v);
printf("%d ",u);
}
int main()
{
scanf("%d%d%d",&n,&m,&d);
for(int i=1; i<=m; i++)
{
int a,b,v,l,t=0;
scanf("%d%d%d%d",&a,&b,&v,&l);
G[a][b]=(point){1,v,l};
}
dijkstra();
double mint=INF;
int speed;
for(int i=0; i<=500; i++)
{
if(dis[d][i]<mint)
{
mint=dis[d][i];
speed=i;
}
}
print(d,speed);
return 0;
}
$$A\ drop\ of\ tear\ blurs\ memories\ of\ the\ past.$$