帮助卡常:如果您使用的是Kruskal算法且90pts
查看原帖
帮助卡常:如果您使用的是Kruskal算法且90pts
567610
RDFZchenyy楼主2022/8/21 17:49

这题对于Kruskal算法OIer极度不友好,在这里提供一个有趣的卡常优化想法。(不想看分析的直接看【写法】)

【分析】

nn == 50005000 时,Kruskal 算法需要处理 1.251.25 ×\times 10810^8 条边,这样庞大的边数 Kruskal 算法肯定吃不消。我们需要牺牲一点正确性来换取时空复杂度。考虑到你实际上只需要 nn - 11 == 50005000 - 11 == 49994999 条边,此时一定需要删除一些无用的边。两个点之间的间距的平均值约是 2\sqrt{2} ×\times 2000000÷50002000000\div5000 == 570570 这个值,我们可以把这个值扩大一些倍数,我选择扩大不到 400400 倍,取一个比较整的数 22 ×\times 10510^5, 为了防止 nn 比较小时漏解,当 nn \le 10001000 时我们正常计算,就可以了。

【写法】

所以我们只对 dis(i,j)dis(i,j) \le 11 ×\times 10610^6 时的边或 nn \le 10001000 时的所有边建边即可

【实现】 我贴出我的代码片段

if(sqrt((x[i]-x[j])*(x[i]-x[j])
  +(y[i]-y[j])*(y[i]-y[j]))<=1000000.0){
	graph[m]=(Edge){i,j,sqrt((x[i]-x[j])*(x[i]-x[j])
	  +(y[i]-y[j])*(y[i]-y[j]))};
	m++;				
}

【提示】

友情提醒,这并不是一篇正经的题解,所以大佬们也就不用费心去 hack 了,还有就是这应该不是正解,别喷,希望写正解的酌情略过。

作者的记录:https://www.luogu.com.cn/record/84675206

2022/8/21 17:49
加载中...