给定m套整数A1,A2,…,Am;这些集合的元素是1到n之间(包括1和n)的整数。
有两个正整数数组a1,a2,...,am和b1,b2,...,bn。
在一个操作中,您可以从集合Ai中删除元素j,并为此支付ai + bj硬币。
您可以执行几个(也许没有)操作(某些集合可能为空)。
在那之后,您将制作一个由n个顶点组成的边色无向图。对于每个集合Ai,您将为所有x,y∈Ai和x <y添加一条颜色为i的边(x,y)。某些顶点对可以连接多个边,但是这些边具有不同的颜色。
如果其上所有边的颜色都不同,则称为循环i1→e1→i2→e2→…→ik→ek→i1(ej是连接顶点ij和ij + 1的某些边)。
找出要获得没有彩虹周期的图表所需的最小硬币数量。
题解:
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+100; typedef long long ll; struct node { int u,v; ll w; bool operator < (const node &r) const { return w>r.w; } }edge[maxn<<2]; int n,m; ll a[maxn]; int father[maxn]; int findfather (int x) { int a=x; while (x!=father[x]) x=father[x]; while (a!=father[a]) { int z=a; a=father[a]; father[z]=x; } return x; } int main () { ll ans=0; int tot=0; scanf("%d%d",&m,&n); for (int i=1;i<=n+m;i++) scanf("%lld",a+i),father[i]=i; for (int i=1;i<=m;i++) { int k; scanf("%d",&k); for (int j=1;j<=k;j++) { int x; scanf("%d",&x); ll v=a[i]+a[m+x];ans+=v; edge[++tot]={i,m+x,v}; } } sort(edge+1,edge+tot+1); for (int i=1;i<=tot;i++) { int x=edge[i].u; int y=edge[i].v; x=findfather(x); y=findfather(y); if (x==y) continue; ans-=edge[i].w; father[y]=x; } printf("%lld ",ans); }