Costo mínimo
Título
Dado un gráfico no dirigido, el peso del borde es wi (0 ≤ wi ≤ 1) w_i (0 \ leq w_i \ leq1)wyo( 0≤wyo≤1 ) . Defina la distancia entre dos puntos como el producto de todos los valores de la ruta. Encuentra el camino más largo entre dos puntos.
Ideas
Suponga que la distancia es w 1 w 2… wk w_1w_2 \ dots w_kw1w2...wk, Se puede procesar mediante logaritmos, es decir, log w 1 w 2… wk = log w 1 + log w 2 +… log wk \ log w_1w_2 \ dots w_k = \ log w_1 + \ log w_2 + \ dots \ log w_klo gw1w2...wk=lo gw1+lo gw2+...lo gwk. De esta forma, la multiplicación se transforma en sumar puntos, para encontrar el camino más largo se puede procesar el número opuesto. Porque wi (0 ≤ wi ≤ 1) w_i (0 \ leq w_i \ leq1)wyo( 0≤wyo≤1 ), 所以log wi ≤ 0 \ log w_i \ leq 0lo gwyo≤0 , todos los números no negativos después de tomar el número opuesto, por lo que se puede utilizar el algoritmo de Dijkstra.
Código
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2010;
int n,m,S,T;
double g[N][N];
double dist[N];
bool st[N];
void dijkstra()
{
dist[S] = 1;
for(int i=1;i<=n;i++){
int t = -1;
for(int j=1;j<=n;j++){
if(!st[j]&&(t==-1||dist[t]<dist[j])){
t = j;
}
}
st[t] = true;
for(int j=1;j<=n;j++){
dist[j] = max(dist[j],dist[t]*g[t][j]);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
double z = (100.0 - c) / 100;
g[a][b] = g[b][a] = max(g[a][b], z);
}
scanf("%d%d",&S,&T);
dijkstra();
printf("%.8f\n",100.0/dist[T]);
return 0;
}
recompensa
- Para encontrar el camino más largo, puede invertir el peso lateral y hacer el camino más corto. De hecho, en el proceso de escribir el código, no es necesario invertirlo, simplemente invertir el signo de desigualdad del triángulo de desigualdad, min minm i n cambiado amax maxm A X puede.
- Para multiplicar, si el peso es menor o igual que 1 11 , entonces es equivalente al peso del lado negativo de la suma; si es mayor que1 1En el caso de 1 , significa el derecho al frente.