算法一:
贪心,如果删除点 $(x,y)$ 整个图仍然联通则删掉 $(x,y)$,否则保留.
想到这里了,但是不会维护两点连通性,看了题解后发现直接令 $c[i][j]$ 表示连通块 $(i,j)$ 之间删掉了多少条边.
如果 $c[i][j]+1=frac { num[i] imes (num[j]-1) }{2}$ 则不能删掉连接 $(i,j)$ 的边,否则可以删掉.
这个用并查集维护,总操作次数是 $O(n^2)$ 的.
算法二:
这个构造方式比较巧妙.
考虑如何构建一颗树:对于点 $i$ ,随机取一个小于 $i$ 的 $j$ 作为父亲.
那么构造思路就是只保留一条树边,也就是说对于点 $x$ 来说,只连一条由 $x$ 指向 $x$ 父亲的边.
于是对于 $x$ 来说,我们等到所有 $(x,y)$ ,$(y leqslant x)$ 的边删掉只剩一条时再加.
这样可以保证加入的最后一条边一定是树边.
code:
#include "game.h" #include <bits/stdc++.h> using namespace std; int cnt[4008]; void initialize(int n) { } int hasEdge(int u, int v) { ++cnt[max(u,v)]; if(cnt[max(u,v)]==max(u,v)) return 1; else return 0; }