You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
3.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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];
}
//这一道题有很多解法(比如:搜索SpfaDijkstra…),但是思想都是一样的,这里只说图论最短路的思路:
//我们用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;
}