Files
python/TangDou/XiTi/1408.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

132 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
#pragma region Dijkstra算法模板
//正无穷
const int INF = 0x3f3f3f3f;
//声明数据的最大维度
const int N = 100;
int n, m;
//初始数据
int mapp[N][N];
bool visited[N];
//距离,就是从1号顶点到其余各个顶点的初始路程
int dist[N];
//与求最短路相比,增加一个path数组,来记录最短路的路径,先将path[i]=-1,之后每次找出最短路的点p后将path[j]=p,用path[j]=i表示从i到j最短路的路径
int path[N];
/**
* 功能:迪杰斯特拉算法
* 试题板子
* @param v 计算哪个节点做为起始点到各节点的距离
*/
void Dijkstra(int v) {
//初始化
for (int i = 1; i <= n; i++) {
dist[i] = mapp[v][i];
visited[i] = 0;
path[i] = -1;
}
visited[v] = 1;
for (int i = 1; i <= n; i++) {
int p, minn = INF;
for (int j = 1; j <= n; j++) {
if (!visited[j] && dist[j] < minn) {
p = j;
minn = dist[j];
}
}
visited[p] = 1;
for (int j = 1; j <= n; j++) {
if (!visited[j] && dist[p] + mapp[p][j] < dist[j]) {
dist[j] = dist[p] + mapp[p][j];
path[j] = p;
}
}
}
return;
}
/**
* 功能:输出路径
* @param s 起点
* @param n 节点数量
*/
void print(int s, int n) {
stack<int> q;
for (int i = 2; i <= n; i++) {
int p = i;
while (path[p] != -1) {
q.push(p);
p = path[p];
}
q.push(p);
cout << s << "-->" << i << " ";
cout << "dis" << ":" << dist[i] << " ";
cout << s;
while (!q.empty()) {
cout << "-->" << q.top();
q.pop();
}
cout << endl;
}
}
#pragma endregion Dijkstra算法模板
int main() {
//输入+输出重定向
freopen("../1408.txt", "r", stdin);
int p, c, m;
cin >> n >> p >> c >> m;
//1、初始化二维数组,全部为一个非常大的数据
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
mapp[i][j] = INF;
}
}
//2、s表示路径的起点,t表示路径的终点,edge表示该路径的长度。
int s, t;
//录入路径
while (p--) {
cin >> s >> t;
//将权写入
mapp[s][t] = 1;
mapp[t][s]=1; //双向写入,就是表示无向图,这一点非常重要!!!
}
//3、调用核心算法: 源点(统一规定为v1)到所有其他各定点的最短路径长度。
Dijkstra(c);
//输出结果
print(c, n);
//找到最长路径
int maxEdge = -1;
for (int i = 2; i <= n; i++) {
if (dist[i] > maxEdge && dist[i] != INF) maxEdge = dist[i];
}
//这一道题有很多解法(比如:搜索,Spfa,Dijkstra…),但是思想都是一样的,这里只说图论最短路的思路:
//我们用Dijkstra(或Spfa),从第 一 个 人 开 始 , 即C小朋友第一个人开始,即C小朋友第一个人开始,即C小朋友,
// 有最短路求到TA到其他小朋友传输的最短时间。之后再求传输时间的最大值(因为最大时间可永远保证其他人传输完毕),最后在最大值的基础上 加上(M+1)这就是答案。
/**
* 【样例解释】
第一秒,糖在1手上。第二秒,糖传到了2、4的手中。第三秒。糖传到了3的手中,此时1吃完了。第四秒,2、4吃完了。第五秒。3吃完了。所以答案是5。
*/
//输出结果
cout << maxEdge + 1 + m << endl;
//关闭文件
fclose(stdin);
return 0;
}