最短路径问题(多权值最短路)(D)

最短路径问题

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11

多权值最短路,用Dijkstra的优化版本,根据不同权值改改优先级队列的运算符重载

#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
struct node{
	int v,d,p;
	node(){}
	node(int vv,int dd,int pp){
		v=vv;
		d=dd;
		p=pp;
	}
}; 
struct Node{
	int u,d,p;
	Node(){}
	Node(int uu,int dd,int pp){
		u=uu;
		d=dd;
		p=pp;
	}
	bool operator<(const Node other)const{
	if(d!=other.d) return d>other.d;//距离短的优先
	else return p>other.p;//如果距离一样,花费少的优先
	}
};
const int maxn=1005;
const int Inf=0x3f3f3f3f;
int n,m,s,t;
vector<node> G[maxn];
bool book[maxn];
int dis[maxn],cost[maxn];
void Dijkstra(){
	priority_queue<Node> q;
	for(int i=1;i<=n;i++){
		dis[i]=Inf,cost[i]=Inf;
		book[i]=false;
	}
	dis[s]=0,cost[s]=0;
	q.push(Node(s,dis[s],cost[s]));
	while(!q.empty()){
		Node temp=q.top();
		q.pop();
		int u=temp.u;
		if(book[u]) continue;
		book[u]=true;
		for(int i=0;i<G[u].size();i++){
			node tmp=G[u][i];
			int v=tmp.v;
			int d=tmp.d;
			int p=tmp.p;
			if(dis[v]>=dis[u]+d){  //注意是大于等于(因为是如果最短距离一样,输出花费最少的)
				dis[v]=dis[u]+d;
				cost[v]=cost[u]+p;
				q.push(Node(v,dis[v],cost[v]));
			}
		}
	}
	printf("%d %d\n",dis[t],cost[t]);
}
int main(){
	int a,b,d,p;
	while(scanf("%d%d",&n,&m)){
		if(n==0&&m==0) break;
		for(int i=1;i<=n;i++)
		G[i].clear();
		for(int i=1;i<=m;i++){
			scanf("%d%d%d%d",&a,&b,&d,&p);
			G[a].push_back(node(b,d,p));
			G[b].push_back(node(a,d,p));
		}
		scanf("%d%d",&s,&t);
		Dijkstra();
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_42936517/article/details/84405453
今日推荐