速度限制
题解:
思路挺好想的一道最短路
与uva一道自行车车轮有几个轮子的那题很像
用二维状态表示一个点
即它的标号和它的速度
代码:
#include <bits/stdc++.h>
using namespace std;
#define maxn 100000
#define exp 1e-9
#define nmaxn 200
#define vmaxn 1000
int n,m,s,t,c,d,e,f,l,o[maxn];
double dis[nmaxn+100][vmaxn+100];
int head[maxn];
bool inq[nmaxn+100][vmaxn+100];
struct re{
int a,b,c,d;
}a[maxn];
#define INF 1e9
void arr(int x,int y,int c,int d)
{
a[++l].a=head[x];
a[l].b=y;
a[l].c=c;
a[l].d=d;
head[x]=l;
}
struct ree{
int a,b;
}tmp,pre[nmaxn+100][vmaxn+100];
queue<ree> q;
int main()
{
cin>>n>>m>>t;
for (int i=1;i<=m;i++)
{
cin>>c>>d>>e>>f;
arr(c,d,e,f);
}
s=0; tmp.a=s; tmp.b=70; q.push(tmp);
memset(inq,1,sizeof(inq));
for (int i=1;i<=nmaxn;i++)
for (int j=0;j<=vmaxn;j++)
dis[i][j]=INF;
while (!q.empty())
{
ree x=q.front();q.pop();
int u=head[x.a];
while (u)
{
int v=a[u].b;
if (a[u].c==0)
{
if (dis[a[u].b][x.b]>dis[x.a][x.b]+(a[u].d+exp)/(x.b+exp))
{
dis[a[u].b][x.b]=dis[x.a][x.b]+(a[u].d+exp)/(x.b+exp);
if (inq[v][x.b])
{
inq[v][x.b]=0;
tmp.a=v;tmp.b=x.b;
q.push(tmp);
}
pre[v][x.b].a=x.a;
pre[v][x.b].b=x.b;
}
} else
{
if (dis[a[u].b][a[u].c]>dis[x.a][x.b]+(a[u].d+exp)/(a[u].c+exp))
{
dis[a[u].b][a[u].c]=dis[x.a][x.b]+(a[u].d+exp)/(a[u].c+exp);
if (inq[v][a[u].c])
{
inq[v][a[u].c]=0;
tmp.a=v; tmp.b=a[u].c;
q.push(tmp);
}
pre[v][a[u].c].a=x.a;
pre[v][a[u].c].b=x.b;
}
}
u=a[u].a;
}
inq[x.a][x.b]=1;
}
double ans=INF;
ree ans2,ans3;
ans2.a=t;
for (int i=1;i<=vmaxn;i++)
if (dis[t][i]<ans)
{
ans=dis[t][i];
ans2.b=i;
}
o[1]=ans2.a; int lo=1;
while (ans2.a!=s)
{
ans3.a=pre[ans2.a][ans2.b].a;
ans3.b=pre[ans2.a][ans2.b].b;
o[++lo]=ans3.a;
ans2=ans3;
}
for (int i=lo;i>=1;i--)
cout<<o[i]<<" ";
}