CF1408E Avoid Rainbow Cycles

CF1408E Avoid Rainbow Cycles

没什么好狡辩的,就是根本想不到(苦笑

其实看起来就很像是需要构图的样子,对于所有 \(j \in A_i\),我们连一条无向边 \((j, A_i)\)

容易发现若原图中有一个环,那么新图也会对应一个环(可以借助这个事实来理解:即连向同一个 \(A_i\) 的两个点在原图中是相连的)

所以问题转化成花最少的代价删边使新图不含环。直接最大生成树就可以了。时间复杂度 \(O(\sum s_i \log {\sum s_i})\)

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
#define int ll 
using namespace std;
using ll = long long;
const int N = 4e5;
struct node{
	int u, v, w;
	bool operator < (const node &other)const{
		return w > other.w;
	}
}e[N];
int n, m, cnt, sum = 0, tt = 0;
int a[N], b[N], fa[N];
int getfather(int x){
	if(fa[x] != x) fa[x] = getfather(fa[x]);
	return fa[x];
}
void kru(){
	F(i, 1, cnt){
		int u, v, w;
		u = getfather(e[i].u);
		v = getfather(e[i].v);
		w = e[i].w;
		if(u != v){
			fa[u] = v;
			tt += w;
		}
	}
}
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> m >> n;
	F(i, 1, n + m) fa[i] = i;
	F(i, 1, m) cin >> a[i];
	F(i, 1, n) cin >> b[i];
	F(i, 1, m){
		int s;
		cin >> s;
		F(j, 1, s){
			int x;
			cin >> x;
			e[++ cnt] = (node){i + n, x, a[i] + b[x]};
			sum += a[i] + b[x];
		}
	}
	sort(e + 1, e + cnt + 1);
	kru();
//	printf("The weight of MaxTree = %lld\n", tt);
	cout << sum - tt << '\n';
	return fflush(0), 0;
}
posted @ 2025-08-15 15:32  superl61  阅读(9)  评论(0)    收藏  举报