最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

刷题——最短路径算法!第二篇

IT圈 admin 3浏览 0评论

刷题——最短路径算法!第二篇

总览

    • C - 草儿是个路痴
    • D - 稀的泥和热的油

C - 草儿是个路痴

虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,0),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
Input
输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。
Output
输出草儿能去某个喜欢的城市的最短时间。
Sample Input
6 2 3
1 3 5
1 4 7
2 8 12
3 8 4
4 9 12
9 10 2
1 2
8 9 10
Sample Output
9
题解
题目意思就是有S个起点,D个终点,求起点到终点所有路径中的最短路。
AC代码:

#include <bits/stdc++.h>
using namespace std;
const int maxe = 100100, maxv = 1100;
const int INF = unsigned(-1) >> 1;
int m, s, n;
struct edge
{int x, y;
};
edge es[maxe]; //边
struct Graph
{int dis;
};
Graph G[maxv][maxv]; //邻接矩阵
struct dist
{int dis;
};
dist d[maxv]; //最短路径
void fun(int s)
{while (true){bool updata = false;for (int i = 0; i < m; i++) //遍历所有的边{edge e = es[i];if (d[e.x].dis != INF) //如果遍历过e.x点{if (d[e.x].dis + G[e.x][e.y].dis < d[e.y].dis) //如果从e.x点走到e.y点的路径 比 其他点走到e.y的路径要短{d[e.y].dis = d[e.x].dis + G[e.x][e.y].dis; //更新e.y的路径为更短的updata = true;}}if (d[e.y].dis != INF) //如果遍历过e.y点{if (d[e.y].dis + G[e.x][e.y].dis < d[e.x].dis) //如果从e.y点走到e.x点的路径 比 其他点走到e.x的路径要短{d[e.x].dis = d[e.y].dis + G[e.x][e.y].dis; //更新e.x的路径为更短的updata = true;}}}if (updata == false) //如果所有的边都遍历过了,路径信息没有更新过,说明已经遍历完了,结束搜索break;}
}
int main()
{while (scanf("%d%d%d", &m, &s, &n) != EOF){int dis;for (int i = 1; i < maxv; i++) //初始化邻接矩阵for (int j = 1; j < maxv; j++)G[i][j].dis = INF;for (int i = 0; i < m; i++){scanf("%d%d%d", &es[i].x, &es[i].y, &dis);if (dis < G[es[i].x][es[i].y].dis) //构建邻接矩阵G[es[i].x][es[i].y].dis = G[es[i].y][es[i].x].dis = dis;}for (int i = 0; i < maxv; i++) //初始化最短距离d[i].dis = INF;int city[maxv];for (int i = 0, x; i < s; i++) //草儿的邻居{scanf("%d", &x);d[x].dis = 0;}for (int i = 0; i < n; i++) //草儿喜欢的城市scanf("%d", city + i);int ans = INF;fun(0);for (int i = 0; i < n; i++){ans = min(ans, d[city[i]].dis);}printf("%d\n", ans);}return 0;
}

D - 稀的泥和热的油

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

现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
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

题解
就一个基本的单源最短路,上Bellman-Ford算法 !
AC代码:

#include <bits/stdc++.h>
using namespace std;
const int maxe = 100100, maxv = 1100;
const int INF = unsigned(-1) >> 1;
int n, m, s, t;
struct edge
{int x, y;
};
edge es[maxe];
struct Graph
{int dis;
};
Graph G[maxv][maxv];
struct dist
{int dis;
};
dist d[maxv];
void fun(int s)
{for (int i = 0; i < n; i++)d[i].dis = INF;d[s].dis = 0;while (true){bool updata = false;for (int i = 0; i < m; i++) //遍历所有的边{edge e = es[i];if (d[e.x].dis != INF) //如果遍历过e.x点{if (d[e.x].dis + G[e.x][e.y].dis < d[e.y].dis) //如果从e.x点走到e.y点的路径 比 其他点走到e.y的路径要短{d[e.y].dis = d[e.x].dis + G[e.x][e.y].dis; //更新e.y的路径为更短的updata = true;}}if (d[e.y].dis != INF) //如果遍历过e.y点{if (d[e.y].dis + G[e.x][e.y].dis < d[e.x].dis) //如果从e.y点走到e.x点的路径 比 其他点走到e.x的路径要短{d[e.x].dis = d[e.y].dis + G[e.x][e.y].dis; //更新e.x的路径为更短的updata = true;}}}if (updata == false) //如果所有的边都遍历过了,路径信息没有更新过,说明已经遍历完了,结束搜索break;}
}
int main()
{while (scanf("%d%d", &n, &m) != EOF){int dis;if (n == 0 && m == 0)break;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)G[i][j].dis = INF;for (int i = 0; i < m; i++){scanf("%d%d%d", &es[i].x, &es[i].y, &dis);if (dis < G[es[i].x][es[i].y].dis)G[es[i].x][es[i].y].dis = G[es[i].y][es[i].x].dis = dis;}scanf("%d%d", &s, &t);fun(s);if (d[t].dis == INF)puts("-1");elseprintf("%d\n", d[t].dis);}return 0;
}

刷题——最短路径算法!第二篇

总览

    • C - 草儿是个路痴
    • D - 稀的泥和热的油

C - 草儿是个路痴

虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,0),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
Input
输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。
Output
输出草儿能去某个喜欢的城市的最短时间。
Sample Input
6 2 3
1 3 5
1 4 7
2 8 12
3 8 4
4 9 12
9 10 2
1 2
8 9 10
Sample Output
9
题解
题目意思就是有S个起点,D个终点,求起点到终点所有路径中的最短路。
AC代码:

#include <bits/stdc++.h>
using namespace std;
const int maxe = 100100, maxv = 1100;
const int INF = unsigned(-1) >> 1;
int m, s, n;
struct edge
{int x, y;
};
edge es[maxe]; //边
struct Graph
{int dis;
};
Graph G[maxv][maxv]; //邻接矩阵
struct dist
{int dis;
};
dist d[maxv]; //最短路径
void fun(int s)
{while (true){bool updata = false;for (int i = 0; i < m; i++) //遍历所有的边{edge e = es[i];if (d[e.x].dis != INF) //如果遍历过e.x点{if (d[e.x].dis + G[e.x][e.y].dis < d[e.y].dis) //如果从e.x点走到e.y点的路径 比 其他点走到e.y的路径要短{d[e.y].dis = d[e.x].dis + G[e.x][e.y].dis; //更新e.y的路径为更短的updata = true;}}if (d[e.y].dis != INF) //如果遍历过e.y点{if (d[e.y].dis + G[e.x][e.y].dis < d[e.x].dis) //如果从e.y点走到e.x点的路径 比 其他点走到e.x的路径要短{d[e.x].dis = d[e.y].dis + G[e.x][e.y].dis; //更新e.x的路径为更短的updata = true;}}}if (updata == false) //如果所有的边都遍历过了,路径信息没有更新过,说明已经遍历完了,结束搜索break;}
}
int main()
{while (scanf("%d%d%d", &m, &s, &n) != EOF){int dis;for (int i = 1; i < maxv; i++) //初始化邻接矩阵for (int j = 1; j < maxv; j++)G[i][j].dis = INF;for (int i = 0; i < m; i++){scanf("%d%d%d", &es[i].x, &es[i].y, &dis);if (dis < G[es[i].x][es[i].y].dis) //构建邻接矩阵G[es[i].x][es[i].y].dis = G[es[i].y][es[i].x].dis = dis;}for (int i = 0; i < maxv; i++) //初始化最短距离d[i].dis = INF;int city[maxv];for (int i = 0, x; i < s; i++) //草儿的邻居{scanf("%d", &x);d[x].dis = 0;}for (int i = 0; i < n; i++) //草儿喜欢的城市scanf("%d", city + i);int ans = INF;fun(0);for (int i = 0; i < n; i++){ans = min(ans, d[city[i]].dis);}printf("%d\n", ans);}return 0;
}

D - 稀的泥和热的油

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

现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
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

题解
就一个基本的单源最短路,上Bellman-Ford算法 !
AC代码:

#include <bits/stdc++.h>
using namespace std;
const int maxe = 100100, maxv = 1100;
const int INF = unsigned(-1) >> 1;
int n, m, s, t;
struct edge
{int x, y;
};
edge es[maxe];
struct Graph
{int dis;
};
Graph G[maxv][maxv];
struct dist
{int dis;
};
dist d[maxv];
void fun(int s)
{for (int i = 0; i < n; i++)d[i].dis = INF;d[s].dis = 0;while (true){bool updata = false;for (int i = 0; i < m; i++) //遍历所有的边{edge e = es[i];if (d[e.x].dis != INF) //如果遍历过e.x点{if (d[e.x].dis + G[e.x][e.y].dis < d[e.y].dis) //如果从e.x点走到e.y点的路径 比 其他点走到e.y的路径要短{d[e.y].dis = d[e.x].dis + G[e.x][e.y].dis; //更新e.y的路径为更短的updata = true;}}if (d[e.y].dis != INF) //如果遍历过e.y点{if (d[e.y].dis + G[e.x][e.y].dis < d[e.x].dis) //如果从e.y点走到e.x点的路径 比 其他点走到e.x的路径要短{d[e.x].dis = d[e.y].dis + G[e.x][e.y].dis; //更新e.x的路径为更短的updata = true;}}}if (updata == false) //如果所有的边都遍历过了,路径信息没有更新过,说明已经遍历完了,结束搜索break;}
}
int main()
{while (scanf("%d%d", &n, &m) != EOF){int dis;if (n == 0 && m == 0)break;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)G[i][j].dis = INF;for (int i = 0; i < m; i++){scanf("%d%d%d", &es[i].x, &es[i].y, &dis);if (dis < G[es[i].x][es[i].y].dis)G[es[i].x][es[i].y].dis = G[es[i].y][es[i].x].dis = dis;}scanf("%d%d", &s, &t);fun(s);if (d[t].dis == INF)puts("-1");elseprintf("%d\n", d[t].dis);}return 0;
}
发布评论

评论列表 (0)

  1. 暂无评论