畅通工程续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 本题目包含多组数据,请处理到文件结束。
Output 对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
Sample Input Sample Output
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;
}
}
}