O problema mais curto caminho (HDU 3790)

tópico Ligue

título Descrição

Está n pontos, m artigo não dirigida extremidades, cada extremidade tem um comprimento d e despesa P, S está começando final t, requer a distância mais curta entre o ponto de partida para o fim do seu custo, a distância mais curta se a pluralidade de vias, a saída do menos caro.

Formato de entrada

Entrada n, m, o número de pontos é 1 ~ N, em seguida, as linhas m, cada número da linha 4-A, B, d, p, indica que há um bordo entre um e para b, e um comprimento de d, é gasto p . O último número da linha é de dois s, T; origem s, final. m é 0 e n no lado de entrada. (1 <n <= 1000, 0 <m <100000, s! = T)

Formato de saída

Uma linha de saída com dois números, a distância mais curta e custo.

ENTRADA DA AMOSTRA

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

Exemplo de saída

9 11

análise

despesas Shortest-D, enquanto mais um juiz para aplicar um modelo para atualizar o custo mínimo na linha, o seguinte são, respectivamente, Dijkstra, SPFA, SPFA código (SLF optimization) algoritmo fonte.

fonte

o 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]);
	}
}

SLF SPFA algoritmos de otimização

#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]);
	}
}
Publicado 19 artigos originais · ganhou elogios 0 · Visualizações 125

Acho que você gosta

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