题目:穿越沙漠有几个区域,每个区域间有路径链接(两点间路径不唯一);
寻找一条路径使得,路径中的最高温度最小(存在多组取距离最小)。
分析:图论、最短路、最小生成树。分两步求解。
首先,寻找到最小的最高温度,這裡使用dijkstra算法;
然後,利用上述最高溫度作為選取路徑的閾值,求最短路,使用dijkstra算法。
说明:第888題╮(╯▽╰)╭。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int oo = 100000000;
// link_begin
typedef struct _link
{
int point;
double R;
double D;
_link* next;
}link;
link* link_head[101];
link link_node[20002];
int link_size;
void link_initial()
{
link_size = 0;
memset(link_head, 0, sizeof(link_head));
memset(link_node, 0, sizeof(link_node));
}
void link_add_edge(int u, int v, double r, double d)
{
link_node[link_size].point = v;
link_node[link_size].R = r;
link_node[link_size].D = d;
link_node[link_size].next = link_head[u];
link_head[u] = &link_node[link_size ++];
}
// link_end
double dist[101];
double temp[101];
int next[101];
int used[101];
double max(double x, double y)
{
return x>y?x:y;
}
int main()
{
int N, E, S, T, X, Y;
double R, D;
while (~scanf("%d%d%d%d",&N,&E,&S,&T)) {
for (int i = 1; i <= N; ++ i) {
dist[i] = oo;
temp[i] = oo;
next[i] = i;
used[i] = 0;
}
link_initial();
for (int i = 1; i <= E; ++ i) {
scanf("%d%d%lf%lf",&X,&Y,&R,&D);
link_add_edge(X, Y, R, D);
link_add_edge(Y, X, R, D);
}
int now = T;
temp[now] = 0;
used[now] = 1;
for (int i = 2; i <= N; ++ i) {
for (link* p = link_head[now]; p; p = p->next) {
if (temp[p->point] > max(temp[now], p->R)) {
temp[p->point] = max(temp[now], p->R);
}
}
double min = oo;
for (int i = 1; i <= N; ++ i) {
if (!used[i] && min > temp[i]) {
now = i;
min = temp[i];
}
}
used[now] = 1;
}
for (int i = 1; i <= N; ++ i) {
used[i] = 0;
}
now = T;
dist[now] = 0;
used[now] = 1;
for (int i = 2; i <= N; ++ i) {
for (link* p = link_head[now]; p; p = p->next) {
if (dist[p->point] > dist[now] + p->D && p->R <= temp[S]) {
dist[p->point] = dist[now] + p->D;
next[p->point] = now;
}
}
double min = oo;
for (int i = 1; i <= N; ++ i) {
if (!used[i] && min > dist[i]) {
now = i;
min = dist[i];
}
}
used[now] = 1;
}
int New = S;
printf("%d",S);
while (New != T) {
printf(" %d",next[New]);
New = next[New];
}
printf("\n%.1lf %.1lf\n",dist[S],temp[S]);
}
return 0;
}