acm-(最小生成树)Grakn Forces 2020 E. Avoid Rainbow Cycles

题面
传送门
本题难在建图上,也就是思维转化这一步挺难想。题意说所有的环必须满足同色,然后我们先手算几个样例就很容易发现如果一个集合中存在至少三个元素,那么必定会形成同色环,可以认为同一个集合中所有的元素形成了一个连通分量,还是一个完全图。这有什么用呢,每当出现完全图的时候我们就需要注意完全图其实不能很好的服务于我们解题的思路,它只是一个表象,事实上这里的完全图可以等价于一颗树,我们将该集合中所有的元素直接与一个该集合的代表点相连即可,假设集合i的代表点是 n + i \mathbf{n+i} n+i,那么我们把集合中所有的点与 n + i \mathbf{n+i} n+i相连即可。为什么这样做可行?我们考察如果原图中出现一个非同色环会怎样,势必会有边从某个集合的点中连出该集合,然后走了一转后又连回来,至于在集合中怎么走动我们并不关心,我们关心的是这条边在集合之间的走向。
于是我们将集合内的点之间的关系都抽象为将点与集合代表点相连的关系,这样的话这些点都能通过代表点到达集合内的其它点,能够很好的简化完全图。然后题目要求删除一些集合的一些点,那么我们只需要删除这些点与集合代表点相连接的那条边就行了。我们最后的目的是让图中只有同色环,也就是让转化后的图中没有环,因为同一集合内的点的关系是一棵树,不存在环,如果整个图出现了环必定是某些集合间存在环,根据题意我们知道这就是非同色环,故我们只需要让整个图变成一棵树即可。
然后题目要求让删除的边权值尽量小,其实就是让树的权值尽量大,这不就是最大生成树吗,直接Kruskal算法即可。

int fa[maxn*2],a[maxn],b[maxn],tot;
int fd(int rt){
	return rt==fa[rt]?rt:(fa[rt]=fd(fa[rt]));
}
struct EDGE{
	int u,v,w;
	bool operator <(const EDGE a)const{
		return w>a.w;
	} 
}e[maxn*2];

int main(){
	int m,n;
	rd(&m,&n);
	rd(a+1,m);
	rd(b+1,n);
	FOR(i,1,m+1){
		int k;
		rd(&k);
		FOR(j,0,k){
			int u;rd(&u);
			e[tot++]={i+n,u,a[i]+b[u]};
		}
	}
	FOR(i,1,n+m+1)fa[i]=i;
	sort(e,e+tot);
	ll ans=0;
	FOR(i,0,tot){
		int u=e[i].u,v=e[i].v,w=e[i].w;
		if(fd(u)==fd(v))ans+=w;
		fa[fd(u)]=fd(v);
	}
	wrn(ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值