#include 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 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; }