1 条题解

  • 0
    @ 2025-8-24 21:43:46

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Eason_AC
    Remember? / AFOed on 2022.6.14 / 彻底死咯

    搬运于2025-08-24 21:43:46,当前版本为作者最后更新于2019-11-02 16:26:10,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    Update

    • 2020.9.13\texttt{2020.9.13} 重新修改了一些格式和 LaTeX\texttt{LaTeX} 方面的问题,并修改了一些措辞,删除了一些废话。

    Content

    给定一个有 nn 个点、mm 条边(每条边边权为 11)的无向图,求从 11 号点到所有点的距离中:

    • 最长最短路径长度最大的点的编号。
    • 最长最短路径的长度。
    • 有多少个点离 11 号点的距离为最长最短路径的长度。

    数据范围:$2\leqslant n\leqslant 50000,1\leqslant m\leqslant 50000$。

    Solution

    可以发现这里每个边的边权是 11,所以先直接跑跑最短路就行了。

    Part 1 Dijkstra+堆优化

    下面的代码展示的是堆优化+ dijkstra\texttt{dijkstra} 的过程,具体思路可以自己画个图加深理解:

    void dj() {
    	memset(dis, 0x3f, sizeof(dis));
    	dis[1] = 0;
    	q.push(make_pair(0, 1));
    	while(!q.empty()) {
    		int x = q.top().second;
    		q.pop();
    		if(vis[x])	continue;
    		vis[x] = 1;
    		for(int i = h[x]; i; i = e[i].nxt) {
    			int v = e[i].to, z = e[i].v;
    			if(dis[v] > dis[x] + z) {
    				dis[v] = dis[x] + z;
    				q.push(make_pair(-dis[v], v));
    			}
    		}
    	}
    }
    

    多说几句写堆优化+ dijkstra\texttt{dijkstra}要注意的:

    1. 一定要记得将 disdis 数组赋初值为 0x3f3f3f!(至于 vis 数组随便,因为它本来的初值都是0)
    2. 不要直接用 memset(dis,0x3f3f3f3f,sizeof(dis))!因为 memset 是按字节赋值的,不然你的程序会炸掉。
    3. 判断是否遍历该点的时候一定要将之前未标记的点标记为 11!不然您的 while 循环会一直循环下去!

    Part 2 正解

    好了,说了这么多,接下来要讲的是处理最大最短路径的问题。

    其实最大最短路径的处理也很简单,首先遍历一遍找出最大最短路径的距离,再遍历看有这个最大最短路径的点的编号是多少,最后统计出这个最大最短路径的数量就可以了,完全暴力。

    Code

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <cmath>
    #include <iostream>
    #include <queue>
    using namespace std;
    
    int n, m, a, b, h[100007], cnt, dis[100007], vis[100007];
    struct edge {
    	int v, to, nxt;
    }e[100007];
    priority_queue<pair<int, int> > q;
    void a_e(int u, int v) {
    	e[++cnt] = (edge){1, v, h[u]}; h[u] = cnt;
    	e[++cnt] = (edge){1, u, h[v]}; h[v] = cnt;
    }
    void dj() {
    	memset(dis, 0x3f, sizeof(dis));
    	dis[1] = 0;
    	q.push(make_pair(0, 1));
    	while(!q.empty()) {
    		int x = q.top().second;
    		q.pop();
    		if(vis[x])	continue;
    		vis[x] = 1;
    		for(int i = h[x]; i; i = e[i].nxt) {
    			int v = e[i].to, z = e[i].v;
    			if(dis[v] > dis[x] + z) {
    				dis[v] = dis[x] + z;
    				q.push(make_pair(-dis[v], v));
    			}
    		}
    	}
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= m; ++i) {
    		scanf("%d%d", &a, &b);
    		a_e(a, b);
    	}
    	dj();
    	int maxi = 0, ans = 0;
    	for(int i = 1; i <= n; ++i)
    		maxi = max(maxi, dis[i]);
    	for(int i = 1; i <= n; ++i)
    		if(dis[i] == maxi) {
    			printf("%d", i);
    			break;
    		}
    	printf(" %d", maxi);
    	for(int i = 1; i <= n; ++i)
    		if(dis[i] == maxi)	ans++;
    	printf(" %d", ans);
    	return 0;
    }
    
    • 1

    信息

    ID
    2016
    时间
    1000ms
    内存
    125MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者