时隔三个月,我竟hack了那道题的题解
查看原帖
时隔三个月,我竟hack了那道题的题解
96197
Minuses楼主2021/2/6 13:44

众所周知,货车运输这道题有至少114514114514种解法,比如树剖,LCA,整体二分,启发式合并等等等等。

我三个月之前学习了启发式合并做法,注意到一片题解中的启发式合并是这么写的:

if(Q[fx].size()>Q[fy].size())swap(fx,fy);

然而并查集的普通启发式合并都是这么写的:

if(siz[fx]>siz[fy])swap(fx,fy);

于是乎,我陷入了深深的疑惑中:这样复杂度能保证吗?

三个月之后,在WC被并查集暴虐的我回到这题的题解区,并且hack掉了它。

这样写的一个问题是如果两边都没有挂询问,那么启发式合并就没用了。考虑到这个性质设计数据,可以设计一条链,然后所有的询问去询问点1点2,所有的点都去和最后一个点连边,边权递增。

代码在运行时会不断地将最后一个点所在集合从大到小增加节点,并且不断访问最后一个点的父亲。

在没有路径压缩的前提下,这样的复杂度是O(n2)O(n^2)的。

// 数据生成器
#include <bits/stdc++.h>

int main() {
    int n = 1e5, m = 5e5 - 1, q = 3e5;
    // 如果太小的话是能n^2跑过的,于是开到了1e5,正常的nlogn做法是可以通过的。
    printf("%d %d\n", n, m);
    for (int i = 1; i <= m; ++i) {
        printf("%d %d %d\n", n, i, i);
    }
    printf("%d\n", q);
    for (int i = 1; i <= q; ++i) {
        printf("%d %d\n", 1, 2);
    }
    return 0;
}

被我hack掉的题解

加了路径压缩或者正确使用启发式合并都可以通过这组数据。

严格来说,因为需要开大数据,所以实际上并不算是hack

2021/2/6 13:44
加载中...