题解:P14912 [NHSPC 2024] 海盗地图

注意到如果对每个点都跑一边最短路的话时间无法接受,但是注意到所有询问的路径长度严格大于 \(\sqrt{n}\)
也就是说,如果我们随机选一个点在这条路径上的概率有 \(\frac{1}{\sqrt{n}}\)。所以我们选 \(x\) 个点,至少有一个在路径上的概率为 \((1-\frac{1}{\sqrt{n}})^x\),所以我们完全正确的概率大于等于 \(((1-\frac{1}{\sqrt{n}})^x)^q\)
注意到这里 \(x\) 越大越好,考虑到时间限制,我们取 \(2000\) 左右即可(其实可以取到 \(1500\) 的,但是更保险)

code

#include<bits/stdc++.h>
using namespace std;
mt19937 myrand(time(nullptr));
int tot , head[10005] , q;
struct edge{
	int to , nxt;
}ed[200005];
void add_edge(int u , int v){
	tot++ , ed[tot].to = v , ed[tot].nxt = head[u] , head[u] = tot;
}
int n , m , dis[2005][10005] , id[2005];
queue<int> Q; 
void bfs(int id , int s){
	Q.push(s);
	for(int i=1;i<=n;i++)dis[id][i] = 0x3f3f3f3f;
	dis[id][s] = 0;
	while(!Q.empty()){
		int u = Q.front();Q.pop();
		for(int j=head[u];j;j=ed[j].nxt){
			int v = ed[j].to;
			if(dis[id][v]>=0x3f3f3f3f)dis[id][v] = dis[id][u] + 1 , Q.push(v);
		}
	}
}
int main(){
	cin >> n >> m >> q;
	for(int i=1;i<=m;i++){
		int u , v;cin >> u >> v;
		add_edge(u,v) , add_edge(v,u);
	}
	for(int i=0;i<2000&&i<n;i++){
		id[i] = myrand() % n + 1;
		bfs(i,id[i]);
	}
	for(int i=1;i<=q;i++){
		int minn = 0x3f3f3f3f , s , t;cin >> s >> t;
		for(int j=0;j<2000&&j<n;j++)minn = min(minn,dis[j][s]+dis[j][t]);
		cout << minn << " ";
	}
	return 0;
}
posted @ 2026-06-25 16:02  虚空远行者  阅读(6)  评论(0)    收藏  举报