El problema del camino más corto (HDU 3790)

tema Enlace

título Descripción

Usted n puntos, m artículo no dirigidos bordes, cada borde tiene una longitud d y gastos P, S usted extremo inicial t, requiere que la distancia más corta desde el punto de partida hasta el final de su coste, la distancia más corta si la pluralidad de rutas, la salida de los menos caros.

Formato de entrada

De entrada n, m, el número de puntos es 1 ~ n, entonces las m filas, cada número de fila 4 a, b, d, p, indica que hay un borde entre una y b, y una longitud de d, se gasta p . El número última línea es dos s, T; origen s, final. m es 0 y n extremo de entrada. (1 <n <= 1,000, 0 <m <100000, s! = T)

Formato de salida

Salida de una línea con dos números, la distancia más corta y el costo.

Ejemplo de entrada

3 2
1 2 5 6
2 3 4 5
1 3
0 0

Ejemplo de salida

9 11

análisis

gastos de corto-D, mientras que uno de los jueces más para aplicar una plantilla para actualizar el costo mínimo en la línea, lo que sigue son, respectivamente, Dijkstra, SPFA, SPFA código (SLF optimización) algoritmo de origen.

fuente

el algoritmo de Dijkstra

#include <bits/stdc++.h>
#define MAXN 1005
#define MAXM 100005
using namespace std;
struct Edge{	//链式前向星建图 
	int v,w,c,next;
	Edge(){};
	Edge(int _v,int _w,int _c,int _next){
		v=_v,w=_w,c=_c,next=_next;
	};
	bool operator <(const Edge a)const{
		if(w!=a.w)return w>a.w;
		else return c>a.c;
	}
}edge[MAXM*2];
int EdgeCount,head[MAXN];
int n,m,s,t,dis[MAXN],cost[MAXN];
bool used[MAXN];
void addEdge(int u,int v,int w,int c)	//链式前向星加边 
{
	edge[++EdgeCount]=Edge(v,w,c,head[u]);
	head[u]=EdgeCount;
}
void dijkstra()
{
	memset(dis,0x3f,sizeof(dis));	//初始化 
	memset(cost,0x3f,sizeof(cost));
	memset(used,false,sizeof(used));
	priority_queue<Edge> q;
	dis[s]=cost[s]=0;
	q.push(Edge{s,0,0,0});
	while(!q.empty()){
		int u=q.top().v;q.pop();
		if(used[u])continue;	//如果已经确定最短路就continue 
		used[u]=true;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w,c=edge[i].c;
			if(dis[v]>dis[u]+w){	//找到新的最短路 
				dis[v]=dis[u]+w;
				cost[v]=cost[u]+c;
				q.push(Edge{v,dis[v],cost[v],0});
			}
			else if(dis[v]==dis[u]+w){	//找到新的最短路最小费用 
				if(cost[v]>cost[u]+w){
					cost[v]=cost[u]+c;
				}
			}
		}
	}
	return ;
}
int main()
{
	while(scanf("%d%d",&n,&m)&&(n||m)){
		memset(head,0,sizeof(head));	//初始化 
		EdgeCount=0;
		for(int i=1;i<=m;i++){	//读入数据 
			int u,v,w,c;
			scanf("%d%d%d%d",&u,&v,&w,&c);
			addEdge(u,v,w,c);
			addEdge(v,u,w,c);
		}
		scanf("%d%d",&s,&t);	//读入起点和终点 
		dijkstra();
		printf("%d %d\n",dis[t],cost[t]);
	}
}

algoritmo SPFA

#include <bits/stdc++.h>
#define MAXN 1005
#define MAXM 100005
using namespace std;
struct Edge{
	int v,w,c,next;
	Edge(){};
	Edge(int _v,int _w,int _c,int _next){
		v=_v,w=_w,c=_c,next=_next;
	};
}edge[MAXM];
int EdgeCount,head[MAXN];
int n,m,s,t,dis[MAXN],cost[MAXN];
int ven[MAXN],nums[MAXN];
void addEdge(int u,int v,int w,int c)
{
	edge[++EdgeCount]=Edge(v,w,c,head[u]);
	head[u]=EdgeCount;	
} 
void SPFA()
{
	memset(dis,0x3f,sizeof(dis));
	memset(cost,0x3f,sizeof(cost));
	memset(ven,0,sizeof(ven));
	memset(nums,0,sizeof(nums));
	queue<int> q;
	dis[s]=cost[s]=0;
	ven[s]=nums[s]=1;
	q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();
		ven[u]=0;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w,c=edge[i].c;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				cost[v]=cost[u]+c;
				if(!ven[v]){
					q.push(v);
					ven[v]=1;
//					nums[v]++;
//					if(nums[v]>n)return false;
				}
			}
			else if(dis[v]==dis[u]+w){
				if(cost[v]>cost[u]+c){
					cost[v]=cost[u]+c;
					if(!ven[v]){
						q.push(v);
						ven[v]=1;
//						nums[v]++;
//						if(nums[v]>n)return false;
					}
				}
			}
		}
	}
//	return true;
}
int main()
{
	while(scanf("%d%d",&n,&m)&&(n||m)){
		memset(head,0,sizeof(head));
		EdgeCount=0;
		for(int i=1;i<=m;i++){
			int u,v,w,c;
			scanf("%d%d%d%d",&u,&v,&w,&c);
			addEdge(u,v,w,c);
			addEdge(v,u,w,c);
		}
		scanf("%d%d",&s,&t);
		SPFA();
		printf("%d %d\n",dis[t],cost[t]);
	}
}

Optimización de Algoritmos SPFA SLF

#include <bits/stdc++.h>
#define MAXN 1005
#define MAXM 100005
using namespace std;
struct Edge{	//链式前向星 
	int v,w,c,next;
	Edge(){};
	Edge(int _v,int _w,int _c,int _next){
		v=_v,w=_w,c=_c,next=_next;
	};
}edge[MAXM];
int EdgeCount,head[MAXN];
int n,m,s,t,dis[MAXN],cost[MAXN];
int ven[MAXN],nums[MAXN];
void addEdge(int u,int v,int w,int c) //链式前向星加边 
{
	edge[++EdgeCount]=Edge(v,w,c,head[u]);
	head[u]=EdgeCount;	
} 
void SPFA()
{
	memset(dis,0x3f,sizeof(dis));	//初始化 
	memset(cost,0x3f,sizeof(cost));
	memset(ven,0,sizeof(ven));
	memset(nums,0,sizeof(nums));
	deque<int> q;
	dis[s]=cost[s]=0;
	ven[s]=nums[s]=1;
	q.push_back(s);
	int cnt;
	while((cnt=q.size())){
		int u=q.front();q.pop_front();
		ven[u]=0;	//取消队列标记 
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w,c=edge[i].c;
			if(dis[v]>dis[u]+w){	//更新最短路 
				dis[v]=dis[u]+w;
				cost[v]=cost[u]+c;
				if(!ven[v]){	//不在队列中 
					if(cnt>1&&dis[v]<dis[q.front()])q.push_front(v);
					else q.push_back(v); 
					ven[v]=1;
//					nums[v]++;
//					if(nums[v]>n)return false;
				}
			}
			else if(dis[v]==dis[u]+w){	//更新最短路最小费用 
				if(cost[v]>cost[u]+c){
					cost[v]=cost[u]+c;
				}
			}
		}
	}
//	return true;
}
int main()
{
	while(scanf("%d%d",&n,&m)&&(n||m)){
		memset(head,0,sizeof(head));	//初始化 
		EdgeCount=0;
		for(int i=1;i<=m;i++){	//读入数据 
			int u,v,w,c;
			scanf("%d%d%d%d",&u,&v,&w,&c);
			addEdge(u,v,w,c);
			addEdge(v,u,w,c);
		}
		scanf("%d%d",&s,&t);	//读入起点和终点 
		SPFA();
		printf("%d %d\n",dis[t],cost[t]);
	}
}
Se han publicado 19 artículos originales · ganado elogios 0 · Vistas 125

Supongo que te gusta

Origin blog.csdn.net/weixin_43960284/article/details/105269428
Recomendado
Clasificación