such that the maximal needed overspeeding along this route is as minimal as possible“一般情况”,看到这句就是二分了。二分答案,跑最短路即可。路径还原什么的。。应该不是问题吧
/*
author:ray007great
*/
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
/* define */
#define sf(a) scanf("%d",&a)
#define sfs(a) scanf("%s",a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repd(i,a,b) for(int i=(a);i>=(b);i--)
#define rep1(i,a,b) for(int i=(a);i<(b);i++)
#define clr(a) memset(a,0,sizeof(a))
#define pfk printf("fuck\n")
/* define */
queue<int> q;
const int N = 11000;
const double inf = 9999999;
const double eps = 1e-8;
struct edge{
int u,v;
double l,s;
int id;
};
vector<edge> g[N];
vector<int> ans;
bool inq[N];
int n,m,path[N];
double d[N];
int fa[N];
double t;
void spfa(double plus){
memset(inq,0,sizeof(inq));
rep(i,2,n) d[i]=inf;
d[1]=0;
q.push(1);
while(!q.empty()){
// pfk;
int u=q.front();q.pop();
inq[u]=false;
int sz=g[u].size();
rep1(i,0,sz){
int v=g[u][i].v;
double w=g[u][i].l/(g[u][i].s+plus);
if(d[v]>d[u]+w){
d[v]=d[u]+w;
fa[v]=u;
path[v]=g[u][i].id;
if(!inq[v]){
inq[v]=true;
q.push(v);
}
}
}
}
}
bool ok(double x){
spfa(x);
if(d[n]<=t) {//
// pfk;
// printf("%lf\n",d[n]);
return true;
}
return false;
}
int main(){
while(~scanf("%d%d",&n,&m)){
ans.clear();
rep(i,1,n) g[i].clear();
rep(i,1,m){
int u,v;
double li,s;
scanf("%d%d%lf%lf",&u,&v,&s,&li);
edge t1,t2;
t1.u=u;t1.v=v;t1.l=li;t1.s=s;t1.id=i;
t2.u=u;t2.v=v;t2.l=li;t2.s=s;t2.id=i;
g[u].push_back(t1);
g[v].push_back(t2);
}
scanf("%lf",&t);
double l=0,r=1e8,m;
while(fabs(l-r)>eps){
// pfk;
m=(l+r)/2;
if(ok(m)) r=m;
else l=m;
// printf("%lf\n",m);
}
for(int i=n;i!=1;i=fa[i]){
ans.push_back(path[i]);
}
int sz=ans.size();
printf("%.6f %d\n",m,sz);
printf("%d",ans[sz-1]);
for(int i=sz-2;i>=0;i--) printf(" %d",ans[i]);
puts("");
}
return 0;
}