求出一条s到t的路径,使得这条路径上经过最高温度最小的前提下,总长度最短。
什么最大值最小很容易想到二分...就每次枚举最高温度然后在这个温度下跑最短路看是否连通。
但是这道题也可以用最小生成树的算法来做qwq
想要温度尽量小,就以温度为关键字,跑一遍最小生成树,就得到了使s,t连通所需要的最小的最高温度。
(注意,这里最小生成树的结束条件是fa(s)==fa(t) )
然后在所有温度不高于这个最高温度的边中跑最短路即可。
话说这题有多组数据啊...
发现
while(scanf("%d%d",&n,&m)!=EOF)
可以写成
while(~scanf("%d%d",&n,&m))
代码如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #define MogeKo qwq #include<algorithm> #include<queue> using namespace std; const int maxn = 2e6+10; const int INF = 0x3f3f3f3f; int n,m,s,t,cnt,num; int fa[maxn],pre[maxn],a[maxn]; int head[maxn],to[maxn],nxt[maxn]; double hot,dis[maxn],val[maxn]; bool vis[maxn]; struct edge { int u,v; double tem,len; bool operator < (const edge & N)const { return tem < N.tem; } } e[maxn]; void add(int x,int y,double z) { to[++cnt] = y; nxt[cnt] = head[x]; head[x] = cnt; val[cnt] = z; } int getfa(int x) { if(fa[x] == x)return x; return fa[x] = getfa(fa[x]); } void init() { cnt = num = 0; memset(head,0,sizeof(head)); memset(nxt,0,sizeof(nxt)); memset(pre,0,sizeof(pre)); memset(vis,0,sizeof(vis)); for(int i = 1; i <= n; i++) { fa[i] = i; dis[i] = INF; } sort(e+1,e+m+1); } void kruskal() { for(int i = 1; i <= m; i++) { int x = getfa(e[i].u); int y = getfa(e[i].v); if(x == y)continue; fa[x] = y; if(getfa(s) == getfa(t)) { hot = e[i].tem; break; } } } void addedge() { for(int i = 1; i <= m; i++) { if(e[i].tem > hot) break; add(e[i].u,e[i].v,e[i].len); add(e[i].v,e[i].u,e[i].len); } } void dijkstra(int s) { priority_queue < pair<double,int>, vector< pair<double,int> >,greater< pair<double,int> > > q; dis[s] = 0; q.push(make_pair(0,s)); while(!q.empty()) { int u = q.top().second; q.pop(); if(vis[u]) continue; vis[u] = true; for(int i = head[u]; i; i = nxt[i]) { int v = to[i]; if(dis[u]+val[i] < dis[v]) { dis[v] = dis[u]+val[i]; pre[v] = u; q.push(make_pair(dis[v],v)); } } } for(int i = t; i ; i = pre[i]) a[++num] = i; } int main() { while(~scanf("%d%d",&n,&m)) { scanf("%d%d",&s,&t); for(int i = 1; i <= m; i++) scanf("%d%d%lf%lf",&e[i].u,&e[i].v,&e[i].tem,&e[i].len); init(); kruskal(); addedge(); dijkstra(s); for(int i = num; i > 1; i--) printf("%d ",a[i]); printf("%d ",a[1]); printf("%.1lf %.1lf ",dis[t],hot); } return 0; }