【题目】
【题解】
把规律看成一张图,就是把同类元素的试剂当作一个点之后,求这个图的最小生成树。注意判不连通的情况。
这里用Kruskal算法求最小生成树。
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+50;
int a[maxn];
int pre[maxn];
struct p{
int u,v;
ll w;
}f[2*maxn];
int Find(int x)
{
return pre[x]==x?pre[x]:pre[x]=Find(pre[x]);
}
bool cmp(p x,p y)
{
return x.w<y.w;
}
int main()
{
int n,m,k; scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=k;i++) pre[i]=i;
int cnt=0;
for(int i=1;i<=m;i++)
{
int x,y; ll w;
scanf("%d%d%lld",&x,&y,&w);
if(a[x]==a[y]) continue;
else
{
f[++cnt].u=a[x];
f[cnt].v=a[y];
f[cnt].w=w;
}
}
sort(f+1,f+cnt+1,cmp);
ll ans=0; int tot=1;
for(int i=1;i<=cnt;i++)
{
int u=Find(f[i].u);
int v=Find(f[i].v);
if(u!=v)
{
pre[u]=v;
ans+=f[i].w;
tot++;
}
if(tot==k) break;
}
if(tot<k) printf("-1\n");
else printf("%lld\n",ans);
return 0;
}