题意:有N个点,E条边,起点S,终点T,每条边都有一个距离值D,和温度值R,问你从S到T的最大温度值最小的情况下距离最短.
分析:二分温度值,然后dijkstra求S到T的最短距离
// File Name: 10816.cpp // Author: zlbing // Created Time: 2013/2/18 0:27:01 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define MAXN 205 struct Edge{ int u,v; double R,D; }; vector<int>G[MAXN]; vector<Edge> edges; double d[MAXN]; struct node{ int u; double cost; bool operator <(const node& a)const{ return cost>a.cost; } }; int p[MAXN]; int S,T; int N,E; double ans; const double eps=1e-8; bool dijkstra(double mid) { priority_queue<node> Q; node t,tt; for(int i=0;i<=N;i++) d[i]=-1; CL(p,-1); t.u=S; t.cost=0; Q.push(t); d[S]=0; while(!Q.empty()) { t=Q.top(); Q.pop(); if(t.u==T){ ans=t.cost; return true; } for(int i=0;i<G[t.u].size();i++) { Edge e=edges[G[t.u][i]]; //printf("e.u--%d e.v---%d e.cost--%lf\n",e.u,e.v,e.D); //printf("e.R---%lf mid--%lf\n",e.R,mid); if(e.R<=mid){ //printf("aaaaaaaaaaa\n"); if(d[e.v]<0||d[e.v]>t.cost+e.D+eps) { tt.u=e.v; tt.cost=t.cost+e.D; d[tt.u]=tt.cost; p[e.v]=e.u; //printf("t.u--%d t.cost--%lf\n",tt.u,tt.cost); Q.push(tt); } } } } return false; } void print(int s,int u) { if(s==u){ printf("%d",s); return; } print(s,p[u]); printf(" %d",u); } int main(){ //freopen("out.txt","w",stdout); while(~scanf("%d%d",&N,&E)) { scanf("%d%d",&S,&T); int a,b; double R,D; double maxn=0,minn=INF; for(int i=0;i<=N;i++)G[i].clear(); edges.clear(); for(int i=0;i<E;i++) { scanf("%d%d%lf%lf",&a,&b,&R,&D); edges.push_back((Edge){a,b,R,D}); edges.push_back((Edge){b,a,R,D}); int m=edges.size(); G[a].push_back(m-2); G[b].push_back(m-1); maxn=max(maxn,R); minn=min(minn,R); } double Left=minn,Right=maxn; while(Right-Left>eps) { double mid=(Left+Right)/2; //printf("Right---%lf Left=---%lf mid---%lf\n",Right,Left,mid); if(dijkstra(mid)) Right=mid; else Left=mid; } dijkstra(Right); print(S,T); printf("\n"); printf("%.1lf %.1lf\n",ans,Right); } return 0; }