这题精度卡了三天。
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=211;
const int maxm=21111;
const double inf=(1e100);
const double eps=1e-8;
int n,m,s,t;
struct HeapNode{
double d;
int u;
bool operator < (const HeapNode &rhs) const {
return d>rhs.d;
}
};
struct edge{
int v,next;
double r,d;
};
struct Dijkstra{
int n,m,tot;
edge edges[maxm];
double d[maxn];
bool done[maxn];
int pre[maxn];
int head[maxn];
void init(int n)
{
this->n=n;
tot=0;
memset(pre,-1,sizeof(pre));
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,double r,double d)
{
edges[tot].v=v;
edges[tot].r=r;
edges[tot].d=d;
edges[tot].next=head[u];
head[u]=tot++;
}
bool dijkstra(int s,double c)
{
priority_queue<HeapNode> pq;
for(int i=0;i<=n;i++) d[i]=inf;
d[s]=0;
memset(done,false,sizeof(done));
pq.push((HeapNode){0,s});
while(!pq.empty())
{
HeapNode x=pq.top();pq.pop();
int u=x.u;
if(done[u]) continue;
done[u]=true;
for(int i=head[u];i!=-1;i=edges[i].next)
{
int v=edges[i].v;
double r=edges[i].r;
double dis=edges[i].d;
if(r<=c&&d[v]>d[u]+dis){
d[v]=d[u]+dis;
pre[v]=u;
pq.push((HeapNode){d[v],v});
}
}
}
if(d[t]<inf) return true;
else return false;
}
void output(int u,int v){
if (u!=v) output(u,pre[v]);
else{
printf("%d",u);
return;
}
printf(" %d",v);
}
};
Dijkstra dij;
int main()
{
while(~scanf("%d%d",&n,&m))
{
scanf("%d%d",&s,&t);
dij.init(n);
double mint=inf,maxt=0;
for(int i=0;i<m;i++){
int u,v;
double r,d;
scanf("%d%d%lf%lf",&u,&v,&r,&d);
dij.addedge(u,v,r,d);
dij.addedge(v,u,r,d);
mint=min(mint,r);
maxt=max(maxt,r);
}
while(mint+eps<maxt)
{
double mid=(mint+maxt)/2;
if(dij.dijkstra(s,mid)) maxt=mid;
else mint=mid;
}
dij.dijkstra(s,maxt);
dij.output(s,t);printf("\n");
printf("%.1f %.1f\n",dij.d[t],maxt);
}
return 0;
}