题目大意
沙漠中有n 个绿洲(编号为1-n)和e 条连接绿洲的双向道路。每条道路都有一个长度d 和一个温度值r 。给定起点绿洲编号s 和终点绿洲编号t ,求出一条s 到t 的路径,使得这条路径上经过的所有道路的最高温度尽量小,如果有多条路径,选择总长度最短的那一条。
输入格式
输入包含多组数据。
每组数据第一行为两个整数n和e 。表示绿洲数量和连接绿洲的道路数量。
每组数据第二行为两个整数s 和t 。表示起点和终点的绿洲编号。
接下来e行,每行包含两个整数x,y 以及两个实数r,d,表明在绿洲x 和y 之间有一条双向道路相连,长度为d ,温度为r。
输出格式
对于输入的每组数据,应输出两行,第一行表示你找到的路线,第二行包含两个实数,为你找出的路线的总长度与途经的最高温度。
先看题意感觉像是要求最短路(其实也是),然后再看觉得还要用最小瓶颈路,然后此题有两个限制,要首先保证最高温度尽量小,所以先考虑温度。
#include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<queue> #include<cstring> #include<vector> using namespace std; const int maxn = 10005; int n, e; int s, t; struct edge { int nxt, to; double dis; } E[maxn<<1]; struct tree { int u, v; double len, temp; friend bool operator<(const tree &a, const tree &b) { return a.temp < b.temp; } } tr[maxn]; bool vis[maxn]; int cnt, tot; int fa[maxn], head[maxn]; vector<int>p; double Dis[maxn], m; void add(int u, int v, double w) { E[++tot].nxt = head[u]; E[tot].to = v; E[tot].dis = w; head[u] = tot; } void ADD(int u, int v, double w, double t) { tr[++cnt].u = u; tr[cnt].v = v; tr[cnt].len = w; tr[cnt].temp = t; } int find(int x) { if(x != fa[x]) fa[x] = find(fa[x]); return fa[x]; } struct node { int u; double d; friend bool operator<(const node &a, const node &b) { return a.d > b.d; } }; priority_queue<node>q; void dijkstra() { for(int i = 1; i <= n; i++) { Dis[i] = 0x3f3f3f; vis[i] = 0; fa[i] = 0; } Dis[s] = 0; q.push((node) { s,Dis[s] }); while(!q.empty()) { int x = q.top().u; q.pop(); if(vis[x]) continue; vis[x] = true; for(int i = head[x]; i; i = E[i].nxt) { int y = E[i].to; if(Dis[y] > Dis[x] + E[i].dis) { Dis[y] =Dis[x] + E[i].dis; fa[y] = x; q.push((node) { y,Dis[y] }); } } } int x = t; p.clear(); while(x != s) { p.push_back(x); x = fa[x]; } p.push_back(s); for(int i = p.size() - 1; i >= 1; i--) printf("%d ",p[i]); printf("%d ", p[0]); } int main() { while(scanf("%d %d", &n, &e) != EOF) { cnt = tot = 0; m = 0; memset(head,0,sizeof(head)); memset(fa,0,sizeof(fa)); scanf("%d %d", &s, &t); double w, tmp; for(int i = 1; i<= e; i++) { int u, v; scanf("%d %d", &u, &v); scanf("%lf %lf", &tmp, &w); ADD(u,v,w,tmp); } for(int i = 1; i <= n; i++) fa[i] = i; sort(tr + 1,tr + 1 + e); for(int i = 1; i <= e; i++) { int x = find(tr[i].u), y = find(tr[i].v); if(x != y) { fa[x] =y; m = max(m,tr[i].temp); if(find(s) == find(t)) break; } } for(int i = 1; i <= e; i++) { if(tr[i].temp > m) break; add(tr[i].u, tr[i].v, tr[i].len); add(tr[i].v, tr[i].u, tr[i].len); } dijkstra(); printf("%.1lf %.1lf ", Dis[t], m); } return 0; }