HDU-1874 - Continuación del proyecto desbloqueado - El camino más corto de Dijkstra

Descripción del Título:

Una provincia finalmente ha construido muchas carreteras después de implementar el plan del proyecto de desbloqueo durante muchos años. Sin embargo, no es bueno tener más carreteras, cada vez que quieres viajar de un pueblo a otro, hay muchos planos de carreteras para elegir, y algunos planes tienen una distancia mucho más corta que otros. Esto es muy problemático para los peatones.
Ahora que conoce el punto de inicio y el punto final, calcule la distancia más corta que necesita recorrer desde el punto inicial hasta el punto final.

ingresar:

Esta pregunta contiene varios conjuntos de datos, procese hasta el final del archivo.
La primera fila de cada grupo de datos contiene dos números enteros positivos N y M (0 <N <200, 0 <M <1000), que representan el número de ciudades existentes y el número de carreteras que se han construido, respectivamente. Las localidades están numeradas del 0 al N-1.
Lo siguiente es la información de la carretera de la línea M. Cada línea tiene tres números enteros A, B, X (0 <= A, B <N, A! = B, 0 <X <10000), lo que indica que hay una carretera de doble sentido de longitud X entre la ciudad A y la ciudad B .
En la siguiente línea, hay dos números enteros S, T (0 <= S, T <N), que representan el punto inicial y el punto final, respectivamente.

Producción:

Para cada grupo de datos, genere la distancia más corta para viajar en una línea. Si no hay ruta de S a T, salida -1.


Ideas:

Obviamente, este es un problema de ruta más corta . Primero, necesitas saber cómo encontrar la ruta más corta. Aquí hay tres algoritmos para encontrar la ruta más corta . Para este problema, aquí se usa el algoritmo de ruta más corta de Dijkstra.

Permítanme hablar primero sobre el principio del algoritmo de Dijkstra : en orden de longitud creciente de la ruta más corta, la ruta más corta desde el punto de origen a los otros puntos se obtiene a su vez.
Simplemente pon:

  1. Encuentre un punto v1 más cercano al punto de inicio s, este punto debe estar directamente desde el punto de origen
  2. Encuentre el camino más corto s veces más corto desde el punto de partida: Solo puede tener dos situaciones, ①desde el punto de origen directamente hasta ②desde el punto de origen a través de v1, antes de llegar al vértice
  3. Por analogía, encuentre el punto más corto cada vez
  4. Cada vez que se encuentra el punto más corto, la distancia entre el punto de partida y todos los puntos debe relajarse, es decir, si pasa este punto y luego llega a los otros puntos, si el camino se acortará
  5. Establezca la matriz auxiliar dist, donde cada componente dist [k] representa: la ruta más corta actualmente obtenida desde el punto de origen hasta los vértices restantes k, el mapa [i] [j] representa la ruta más corta desde el vértice i al vértice j
  6. Ecuación de transición de estado: suponga que u es el nodo de ruta más corto recién obtenido,dist[k]=min(dist[k],map[u][k]+dist[u]

Veamos el proceso de encontrar el camino más corto a través de un método gráfico:

Inserte la descripción de la imagen aquí


Encuentre el camino más corto desde v0 hasta los puntos restantes:

  1. Las distancias de v0 a v1-v5 son ∞, 10, ∞, 30, 100 en orden
  2. El punto más cercano a v0 es v2, la distancia es 10 y luego se realiza la operación de relajación. Después del punto v2, la distancia de v0 a los otros puntos se convierte en ∞, 10, 60, 30, 100
  3. En este momento, el punto más cercano a v0 es v4 (el punto del camino más corto que se ha encontrado antes no necesita realizar la operación de relajación), continúe la operación de relajación, la distancia de v0 a cada punto se convierte en ∞, 10, 50, 30, 90
  4. Y así sucesivamente, hasta el último punto.

La siguiente tabla es una simulación de cómo encontrar el camino más corto:

Inserte la descripción de la imagen aquí


Aquí está el código:

#include <iostream>
using namespace std;
#define inf 0x3f3f3f3f
#define M 201
int visit[M],map[M][M],dist[M];
int main()
{
    
    
	int n,m,a,b,dis,start,Min,next,targe;
	while(cin>>n>>m)
	{
    
    	
		for(int i=0;i<n;i++)
		{
    
    
			visit[i]=0;
			dist[i]=inf;
			for(int j=0;j<n;j++)
			{
    
    
				map[i][j]=inf;
			}
		}
		
		while(m--)
		{
    
    
			cin>>a>>b>>dis;
			map[a][b]=min(map[a][b],dis);
			map[b][a]=map[a][b]; 
		}
		
		cin>>start>>targe;
		dist[start]=0;
		visit[start]=1;//visit[i]=1表示点i已经是最短路径,不需要再进行松弛操作 
		while(start!=targe)
		{
    
    
			Min=inf;
			for(int i=0;i<n;i++)
			{
    
    
				if(map[start][i]!=inf)
					dist[i]=min(dist[i],map[start][i]+dist[start]);
				if(!visit[i]&&dist[i]<Min)
				{
    
    
					next=i;//寻找当前距离起点最近的点 
					Min=dist[i];
				}			
			}	
			if(Min==inf) break;
			start=next;//下一个开始的点就是当前距离起点最近的点 
			visit[start]=1;		
		}
		if(dist[targe]==inf) cout<<"-1"<<endl;
			else cout<<dist[targe]<<endl;	
	}	
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45102820/article/details/114379538
Recomendado
Clasificación