文章目录

  • 7-9 哈利波特的考试
  • 7-8 旅游规划
  • 7-10 公路村村通

之所以把 7-8,7-9,7-10 放到一起,是因为这三个题都是非常经典的图算法,在之前总结的算法笔记中已经提到过,这里只是做一个复习,所以整理到一起。

发现自己的记忆力是真的不行,还是需要勤加努力多认真学习才能把这些算法都掌握住。

7-9 哈利波特的考试

这道题目是想考全局最短路径,Floyd 算法,直接使用 Floyd 算法即可。

关于 Floyd 算法主要是用来求全局最短路径,我们这里给出一份 Floyd算法 的伪代码:

枚举顶点 k 属于 [1, n]以顶点 k 作为中介点,枚举所有顶点对 i 和 j如果 dis[i][k] + dis[k][j] < dis[i][j]赋值 dis[i][j] = dis[i][k] + dis[k][j]

但是个人觉得这道题目的难度在于读题 TAT,我读题读了半才读懂是什么意思,看来还是需要提高阅读能力。

完整的解题过程如下:

/*Author: Veeupup哈利波特的考试*/
#include <iostream>
#include <cstdio>
#include <cstdint>
#include <climits>
using namespace std;const int maxn = 110, INF = 1e5;int n, m;
int dis[maxn][maxn];// 朴素的 floyd 算法,求全局最短路径
void floyd() {for (int k = 1; k <= n; k++)for (int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}int main()
{freopen("data.txt","r", stdin);    scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++){   // 初始化点之间的距离,自己到自己距离为 0for (int j = 1; j <= n; j++){if(i == j) dis[i][j] = 0;else dis[i][j] = INF;}}int v1, v2, weight;for (int i = 1; i <= m; i++){scanf("%d%d%d", &v1, &v2, &weight);dis[v1][v2] = dis[v2][v1] = weight;}floyd();int ans = INF;int cnt = 0;for (int i = 1; i <= n; i++){int Max = 0;for (int j = 1; j <= n; j++){if(dis[i][j] == INF) {   // 如果有孤立的结点,那么就无法完成变形printf("0");return 0;}Max = max(Max, dis[i][j]);}if(Max < ans) {ans = Max;cnt = i;}}printf("%d %d", cnt, ans);return 0;
}

7-8 旅游规划

这道题是很经典的具有多个标尺的单源最短路径的变形,我们使用 Dijkstra + DFS 来实现多个标尺的计算,不用在 Dijkstra 中将原算法修改的很复杂。

关于 Dijkstra + DFS 可以参考这里的文章来进行复习。

下面给出完整代码实现:

/*Author: Veeupup旅游规划单源最短路径 Dijkstra,有两个标尺 1. 距离 2. 过路费典型的单源最短路径的变形*/
#include <iostream>
#include <cstdio>
#include <cstdint>
#include <vector>
using namespace std;const int maxn = 510, INF = 1e4;int N, M, S, D;
int G[maxn][maxn];  // 保存距离,第一标尺
int cost[maxn][maxn]; // 保存收费金额,图的边权
int dis[maxn], minCost = INF;  // 记录起点到某点的最小距离
bool vis[maxn] = {false};   // 记录是否访问过vector<int> pre[maxn];  // 保存前一个结点
vector<int> tempPath, path;void Initial()
{   // 初始化距离和花费最大fill(G[0], G[0] + maxn * maxn, INF);fill(cost[0], cost[0] + maxn * maxn, INF);
}void Dijkstra(int S) {fill(dis, dis+maxn, INF);   // 初始化到所有点距离无限大dis[S] = 0; // 到自己距离为 0for (int i = 0; i < N; i++){int u = -1, MIN = INF;for (int j = 0; j < N; j++){   // 寻找未访问的距离最小值if(vis[j] == false && dis[j] < MIN) {u = j;MIN = dis[j];}}if(u == -1) break;  // 所有可以到达的点都访问过了vis[u] = true;  // 设置为已访问for (int v = 0; v < N; v++){   // 遍历能从 u 出发到达的所有点// 如果经过 u 到达 v 更近,那么就更新 vif(dis[u] + G[u][v] < dis[v]) {dis[v] = dis[u] + G[u][v];pre[v].clear();pre[v].push_back(u);    // 经过 u 能够更近的到达 v}else if(dis[u] + G[u][v] == dis[v]) {// 如果经过 u 到达的时候距离一样远,那么增加到其前面去pre[v].push_back(u);}   }}
}void DFS(int V) {if(V == S) {tempPath.push_back(S);int tempCost = 0;int nowId, nextId;for (int i = tempPath.size()-1; i > 0; i--){nowId = tempPath[i];nextId = tempPath[i-1];tempCost += cost[nowId][nextId];}if(tempCost < minCost) {minCost = tempCost;path = tempPath;}tempPath.pop_back();return;}else {tempPath.push_back(V);for (int i = 0; i < pre[V].size(); i++){DFS(pre[V][i]);}tempPath.pop_back();}
}int main()
{freopen("data.txt","r", stdin);Initial();scanf("%d%d%d%d", &N, &M, &S, &D);int u, v;for (int i = 0; i < M; i++){   // 读取图信息scanf("%d%d", &u, &v);scanf("%d%d", &G[u][v], &cost[u][v]);G[v][u] = G[u][v];cost[v][u] = cost[u][v];}Dijkstra(S);DFS(D);   // 从终点向前回溯printf("%d %d\n", dis[D], minCost);return 0;}

7-10 公路村村通

这道题是非常经典的最小生成树算法,推荐使用kruskal算法。

这个题没什么特殊的地方,掌握好最小生成树算法即可,又复习了一遍图算法吧。

完整代码如下:

/*Author: Veeupup公路村村通最小生成树算法:Prim(类似Dijkstra) + Krusktal(边贪心)这里选择使用 Krusktal 算法来实现算法思想很简单*/
#include <iostream>
#include <cstdio>
#include <cstdint>
#include <algorithm>
using namespace std;const int maxn = 1010, INF = INT32_MAX;int N, M;
struct edge
{int u, v;int cost; // 边权
} E[maxn * 3];bool cmp(edge a, edge b)
{return a.cost < b.cost;
}// 使用并查集
int father[maxn];
int findFather(int x)
{while (x != father[x]){x = father[x];}return x;
}// n 为顶点个数, m 为图的边数
int kruskal(int n, int m)
{// ans 为所求边权之和int ans = 0, Num_edge = 0;for (int i = 1; i <= n; i++){father[i] = i;} // 并查集初始化sort(E, E + m, cmp);for (int i = 0; i < m; i++){int faU = findFather(E[i].u);int faV = findFather(E[i].v);if (faU != faV){father[faU] = faV;ans += E[i].cost;Num_edge++;if (Num_edge == n - 1)break;}}if (Num_edge != n - 1)return -1;return ans;
}int main()
{freopen("data.txt", "r", stdin);scanf("%d%d", &N, &M);int u, v, w;for (int i = 0; i < M; i++){scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].cost);}int ans = kruskal(N, M);printf("%d", ans);return 0;
}

希望对大家有帮助。

7-8 哈利·波特的考试,7-9 旅游规划,7-10 公路村村通相关推荐

  1. pta 哈利·波特的考试

    哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变化的魔咒就是简单地将原来的魔咒倒过来念 ...

  2. 【floyd模板】哈利·波特的考试 (25 分)

    立志用最少的代码做最高效的表达 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变化的魔 ...

  3. 7-8 哈利·波特的考试 (25 分)(详解+思路分析)真香啊

    一:题目: 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变化的魔咒就是简单地将原来的 ...

  4. 07-图4 哈利·波特的考试 (25 分)

    哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变化的魔咒就是简单地将原来的魔咒倒过来念 ...

  5. 7-4 哈利·波特的考试 (25 分)(C语言实现)

    7-4 哈利·波特的考试 (25 分) 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向 ...

  6. 7-6 哈利·波特的考试 (8 分)

    7-6 哈利·波特的考试 (8 分) 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变 ...

  7. 数据结构与算法A实验六图论---7-2 哈利·波特的考试(Flody算法)

    哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变化的魔咒就是简单地将原来的魔咒倒过来念 ...

  8. 07-图4 哈利·波特的考试

    哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变化的魔咒就是简单地将原来的魔咒倒过来念 ...

  9. 7-8 哈利·波特的考试

    哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变化的魔咒就是简单地将原来的魔咒倒过来念 ...

  10. 7-8 哈利·波特的考试 (25 分)

    7-8 哈利·波特的考试 (25 分) 看懂题,比较简单. 用Floyd算法. 1.首先将数据读入,用来初始化图 2.用Floyd得到最短路径(各点到各点的全部最短路径). 3.先求出每个点到其它点的 ...

最新文章

  1. iOS开发技巧(系列十八:扩展UIColor,支持十六进制颜色设置)
  2. 一场B站服务端开发面试之旅
  3. 在ASP.NET Core应用程序中使用分布式缓存
  4. c语言中指针数组赋值字符串,C语言—用结构体指针给数组赋值(结构体指针指向字符串,给字符串赋值)...
  5. 开箱即用!这个神器,拯救了无数算法工程师……
  6. iis7 上传限制问题
  7. 作者:孙卫强(1976-),男,博士,上海交通大学教授、博士生导师,主要研究方向为大数据网络、信息通信网等。...
  8. golang结构体tag的使用
  9. PHP教程 数据库和MySQL_PHP教程 - MySQL 创建数据库和表
  10. 【Flink】The Kryo Output still contains data from a previous serialize call. It has to be flushed or
  11. 神奇的go语言(高级应用)
  12. VC双缓冲画图技术介绍
  13. 回顾一个考务系统的开发
  14. MFC与stdafx
  15. python FTPS使用ftplib下载文件(详细)
  16. 【文献阅读】RL经典:Benchmarking Deep Reinforcement Learning for Continuous Control
  17. [侯捷]C++ STL 体系结构与内核分析--从平地到万丈高楼(数据结构)
  18. 防止用户将表单重复提交的方法汇总
  19. Riemann积分和Lebesgue积分角度下一积分不等式的等号成立充要条件的研究
  20. 姚期智亲任主编,正规军的高中AI教材来了

热门文章

  1. 魔百和CM311-1a YST免拆机卡刷精简固件
  2. com.apple.Boot.plist 和SMBIOS.plist 的设置
  3. Kali渗透测试:Metasploit 6.0 中的Evasion模块
  4. Q12矩阵中的路径 回溯法
  5. java lame_音视频编解码——LAME
  6. 前端大屏幕项目大厂解决兼容问题(react)
  7. ios开发读取剪切板的内容_iOS开发之详解剪贴板
  8. PHP 生成 csv 文件时乱码解决
  9. 两个VB程序之交换数据的DDE工程
  10. android网络工程师,网络工程师考试app下载-网络工程师考试 安卓版v3.0.7-PC6安卓网...