http://acm.hust.edu.cn:8080/judge/problem/viewProblem.action?id=19157
關鍵:將溫度進行二分,每個二分溫度進行SPFA求出最短路
#include<iostream>#include<vector>#include<map>#include<stack>#include<algorithm>#include<queue>#include<list>#include<set>#include<string.h>#include<stdlib.h>#include<math.h>#include<stdio.h>#include<ctype.h>#include<iomanip>using namespace std;#define LL long long#define pi acos(-1)#define N 1010#define INF 999999999double dis[N];int pre[N];int vis[N];int s,t;int n,m;struct node{ int next; double w,l;};vector<node> v[N];void init(){ int i; for(i=1;i<=n;i++) v[i].clear();}double spfa(double k){ int i,j; queue<int> q; for(i=1;i<=n;i++) dis[i]=INF; dis[s]=0; memset(vis,0,sizeof(vis)); vis[s]=1; while(!q.empty())q.pop(); q.push(s); while(!q.empty()) { int temp=q.front(); q.pop(); vis[temp]=0; for(i=0;i<(int)v[temp].size();i++) { int to=v[temp][i].next; if(dis[to]>dis[temp]+v[temp][i].l && v[temp][i].w<=k) { dis[to]=dis[temp]+v[temp][i].l; if(!vis[to]) { vis[to]=1; q.push(to); } pre[to]=temp; } } } return dis[t];}void print(int x){ if(x==s) { printf("%d ",s); return ; } print(pre[x]); if(x==t) printf("%d\n",t); else printf("%d ",x);}int main(){// freopen("a.txt","r",stdin); int i,j,k; while(scanf("%d%d",&n,&m)!=EOF) { scanf("%d%d",&s,&t); init(); int a,b; double w,l; node p; double le=INF,r=0,mid; for(i=0;i<m;i++) { scanf("%d%d%lf%lf",&a,&b,&w,&l); p.next=b, p.w=w, p.l=l; v[a].push_back(p); p.next=a; v[b].push_back(p); if(w<le)le=w; if(w>r)r=w; } while(fabs(r-le)>1e-8) { mid=(le+r)/2; //cout<<le<<" "<<mid<<" "<<r<<endl; double len=spfa(mid); if(len!=INF) r=mid; else le=mid; } double ans=spfa(r); print(t); printf("%.1f %.1f\n",ans,r); } return 0;}