畅通工程续(单元最短路径,dijkstra)(优先队列,重载运算符)

畅通工程续

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 87181    Accepted Submission(s): 33604


 

Problem Description

某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。

现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。

 

Input

本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。

 

Output

对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.

 

Sample Input

3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2

Sample Output

2
-1


 

Author

linle

最大的INT

#include <iostream>
using namespace std;


int MAX_INT = 0x7FFFFFFF;
// 7 代表 0111   F代表1111
// 整个二进制是 0111 1111 1111 1111 1111 1111 1111 1111 

int main() {
	
	cout << MAX_INT << endl; 
	printf("%d", MAX_INT);
	/*
	2147483647
	2147483647
	*/
	
}

图的表示

邻接矩阵:表格

邻接表:顶点、邻接边

#include <iostream>
#include <queue>
using namespace std;


/* 这个就是邻接表,是图的信息,需要我输入 */
typedef struct Edge {
	int start;
	int end;
	int length;

	Edge(int start, int end, int length) {
		this->start = start;
		this->end = end;
		this->length = length;
	}
	void print() {
		printf("start:%d,end:%d,length""%d\n",start,end,length);
	}

} Edge;

vector<Edge> graph[201]; //index下标表示顶点,内容是vector<Edge> 一堆并列的,没有链接,表示从这个下标index顶点 到别的顶点的边


/*
因为实际情况 我是一圈一圈,把点加到我的s集合里面
我是找下一个 离我s集合最近的点,其实就是离源点最近的点Point,
然后看这个Point 发散出去的路径,是否比我当前路径更优,优化dis。
*/

typedef struct Point {
	int num; // 顶点编号
	int distanceFromStart; //  从开始 到这个点的距离 // 这个属性 唯一的用处 在于q里面排队的时候,前面的是距离小的


	/*
	优先队列的机制 与 sort 不同
	重载小于号,内部需要大于号!!
	优先队列的机制是  遇到true,交换位置
	如果依照sort的写法:重载小于号,内部也是小于号
	   a < b 是我需要的, 这时候返回true,其实他会给他交换位置,最后得到b a  这就交换了位置  不应该。
	如果重载小于号,内部写a > b
	那么 如果遇到 a < b 他返回 false, 结果不交换, 真的就是保持原样了。

	*/
	// 距离小的 优先级高
	// 排在最前面的,其实是数字最小的  一定要注意 这两个符号是相反的
	bool operator < (const Point& a) const { // 一定要加这个const ,总忘了!
		return distanceFromStart > a.distanceFromStart;
	}
	Point(int num, int distance) {
		this->num = num;
		this->distanceFromStart = distance;
	}

} Point;




const int MAX_INT = 99999;  // 把前面的7省了 我怕出错!
const int INF = MAX_INT;
int dis[201]; // 源点到各个顶点的min距离


int n, m;
// 顶点是0 ~ n-1 共n个
// m个边
int u , v;

void dijkstra(int u) {
	/*
	主要任务: 把所有Point装到q里面走一遍
	填充好dis数组
	*/

	priority_queue<Point> q;
	dis[u] = 0; // 我自己到我自己肯定是0
	q.push(Point(u,0));
	while (!q.empty()) {
		int father = q.top().num; // 离u最近的点
//		cout << father << endl;
		q.pop();
		for (int i = 0; i <= graph[father].size() - 1; i ++) {
			int s = graph[father][i].start; // s肯定是father 不用想了
			int e = graph[father][i].end;
			int l = graph[father][i].length;
			if (dis[e] > dis[s] + l) {
				dis[e] = dis[s] + l;
//				cout << "更新成功" << endl;
				q.push(Point(e,dis[e])); 	// 一定写在括号内,只有更新成功的 才加入q
			}

		}
	}
	return ;
}


void print() {
	cout << "graph" << endl;
	for (int i = 0; i <= n-1; i ++) {
		cout << "index:" << i << endl;
		for (int j = 0; j <= graph[i].size() - 1; j++) {
			graph[i][j].print();
		}

	}
}


int main() {

	while(cin >> n >> m) {
		// 图初始化  没有边
		// 初始情况: 每条最短路径都是INF
		for(int i = 0; i <= n-1; i++) {
			graph[i].clear();
		}
		for (int i = 0; i <= n-1; i++) {
			dis[i] = INF;
		}

		int start, end , length;
		while(m--) {
			cin >> start >> end >> length;
			graph[start].push_back(Edge(start,end,length));
			graph[end].push_back(Edge(end,start,length));
		}

//		print();  // 经验证,没问题
		cin >> u >> v; // 我要找的是 u 到 v的最短路径

		dijkstra(u);
		if (dis[v] == INF) {
			cout << -1 << endl;
		} else {
			cout << dis[v] << endl;
		}
	}


}
#include <iostream>
#include <queue>
#include <vector>
using namespace std;


/*图*/
typedef struct Edge {
	int s; // start
	int e; // end
	int l; // lengh

	Edge(int s,int e, int l) {
		this->s = s;
		this->e = e;
		this->l = l;
	}
} Edge;

vector<Edge> graph[201];

/* s集合,距离表*/
typedef struct Point {
	int num; // 这个点的编号
	int distanceFromStart; // 距离源点的距离

	// 让 distance最小的 排在前面
	bool operator < (const Point& a) const {
		return distanceFromStart > a.distanceFromStart;
	}
	Point(int n,int d) {
		this->num = n;
		this->distanceFromStart = d;
	}
} Point;

int INF = 99999;
int dis[201];

int n, m; // 图的信息  0 - n-1编号 ; m个边
int u, v; // 起点 终点

void dijkstra(int u) {
	priority_queue<Point> q;
	dis[u] = 0;
	q.push(Point(u,0));
	while (!q.empty()) {
		int father = q.top().num;
//		cout << father << endl;
		q.pop();
		for (int i = 0; i <= graph[father].size() - 1; i++) {
			int s = graph[father][i].s;
			int e = graph[father][i].e;
			int l = graph[father][i].l;
			if (dis[e] > dis[s] + l) {
				dis[e] = dis[s] + l;
				q.push(Point(e,dis[e]));
			}

		}

	}
	return ;
}



int main() {
	while (cin >> n >> m) {
		// 初始信息 ok
		for (int i = 0; i <= n-1; i++) {
			graph[i].clear();
		}
		for (int i = 0; i <= n-1; i++) {
			dis[i] = INF;
		}

		//输入 ok
		int s, e, l;
		while(m --) {
			cin >> s >> e >> l;
			graph[s].push_back(Edge(s, e, l));
			graph[e].push_back(Edge(e, s, l));
		}

		// 计算好dis数组
		cin >> u >> v;
		dijkstra(u);
		if (dis[v] == INF) {
			cout << -1 << endl;
		} else {
			cout << dis[v] << endl;
		}

	}



}
发布了126 篇原创文章 · 获赞 2 · 访问量 6326

猜你喜欢

转载自blog.csdn.net/bijingrui/article/details/105373533