题解 | #最短路径问题#

最短路径问题

http://www.nowcoder.com/practice/e372b623d0874ce2915c663d881a3ff2

好麻烦的题型,格式化的流程都这么长

#include <cstdio>
#include <iostream>
#include <vector>
#include <cstring>
#include <queue>
#include <climits>

using namespace std;

const int MAXN = 1001;
const int INF = INT_MAX;

class Edge{
public:
	int to;
	int length;
	int price;
	Edge(int t, int l, int p): to(t), length(l), price(p){}
};

class Point{
public:
	int number;
	int distance;
	Point(int n, int d):number(n),distance(d){}
	bool operator<(const Point &p) const{
		return distance > p.distance;
	}
};

vector<Edge> graph[MAXN];//是实现了 邻接表  所以才只有to没有from 积累!“边数组”实现邻接表
int dis[MAXN];//源点到各点距离
int cost[MAXN];

void Dijkstra(int x){
	priority_queue<Point> q;
	dis[x] = 0;
	cost[x] = 0;
	q.push(Point(x, dis[x]));
	while(!q.empty()){
		int u = q.top().number;//离源点最近的点
		q.pop();
		for(int i=0; i<graph[u].size(); i++){//只有通过u能摸的那些结点才有可能被更新 
			int t = graph[u][i].to;
			int l = graph[u][i].length;
			int p = graph[u][i].price;
			if(dis[t]==dis[u]+l && cost[t]>cost[u]+p || dis[t]>dis[u]+l){
				dis[t] = dis[u] + l;
				cost[t] = cost[u] + p;
				q.push(Point(t, dis[t]));//如果后续push进了距离更短的同一个点t,之前那个t会在被pop出来之后进不了这个if 
			}
		} 
	}
	return;
} 

int main(){
	int n, m;
	while(scanf("%d%d", &n, &m) != EOF){
		if(!n && !m){
			break;
		}
		memset(graph, 0, sizeof(graph));//这啥意思,把vector<Edge>数组初始化为0 ?
		fill(dis, dis+n+1, INF);
		fill(cost, cost+n+1, INF);
		while(m--){
			int from, to, length, price;
			scanf("%d%d%d%d", &from, &to, &length, &price);
			graph[from].push_back(Edge(to, length, price));
			graph[to].push_back(Edge(from, length, price));
		}
		int x, t;
		scanf("%d%d", &x, &t);
		Dijkstra(x);
		printf("%d %d\n", dis[t], cost[t]);
	} 
	return 0;
}
全部评论

相关推荐

我已成为0offer的糕手:别惯着,胆子都是练出来的,这里认怂了,那以后被裁应届被拖工资还敢抗争?
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务