【luogu2700】逐个击破

并查集,加最小生成树技巧。循环搜索边的最大权值,如果边两边是需要隔离开的,则删除该边。
直接考虑原问题比较困难,我们可以这么想:删去的最少=留下来的最多。
那么我们考虑用类似于最小生成树的思想。在使用Kruskal算法时,并查集还要保存一个是否已经有敌人的城市。然后合并的时候必须要两个集合不是都有敌人的城市(最多只有一个集合有敌人的城市)才可以合并。

#include
#define N 110000
struct node1{
	int x,y,z;
};
struct node2{
	bool f;int father;
};
node1 data[N];
node2 a[N];
int aa,n,k,h[N];
int gf(int x){
	if (a[x].father==x) return x;
	a[x].father=gf(a[x].father);
	return (a[x].father);
	
}
void qsort(int l,int r){
	int i=l,j=r,mid=(data[(l+r)/2].z);
	node1 t;
	while (i<=j){
		while (data[i].z>mid)++i;
		while (data[j].z

你可能感兴趣的:(生成树,并查集)