The shortest path problem (HDU 3790)

Topic Link

Title Description

You n points, m article undirected edges, each edge has a length d and expense p, s you starting end t, requires the shortest distance from the starting point to the end of its cost, the shortest distance if the plurality of routes, the output of the least expensive.

Input Format

Input n, m, the number of points is 1 ~ n, then the m rows, each row number 4 a, B, d, p, indicates there is an edge between a and to b, and a length of d, is spent p . The last line number is two s, T; origin s, end. m is 0 and n input end. (1 <n <= 1000, 0 <m <100000, s! = T)

Output Format

Output a line with two numbers, the shortest distance and cost.

SAMPLE INPUT

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

Sample Output

9 11

analysis

Shortest-D expenses, while one more judge to apply a template to update the minimum cost on the line, the following are respectively Dijkstra, SPFA, SPFA (SLF optimization) algorithm source code.

Source

Dijkstra's algorithm

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

SPFA algorithm

#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 Algorithms Optimization

#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]);
	}
}
Published 19 original articles · won praise 0 · Views 125

Guess you like

Origin blog.csdn.net/weixin_43960284/article/details/105269428