这道题的解法居然是最小生成树,根本看不出来啊,果然图论难就难在你根本看不出来它是图论。
把同类元素的试剂当作一个点之后,把花费的脑力作为边权,求这个图的最小生成树即可。
人尽皆知求MST通常选用克鲁斯卡尔,然而笔者的克鲁斯卡尔是没有灵魂的,就是生硬的模板,看到标程的代码以后惊为天人,所以在学会以后决定用博客记录下来。
代码如下
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
vector<tuple<int,int,int>> g;
int a[maxn];
int f[maxn];
int func(int x)
{
return f[x]==x?x:f[x]=func(f[x]);
}
int main()
{
ios_base::sync_with_stdio(0);
int n,m,k;
cin>>n>>m>>k;
iota(f+1,f+n+1,1);
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int u,v,c;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>c;
g.emplace_back(c,a[u],a[v]);
}
sort(g.begin(),g.end());
long long ans=0;
int cnt=0;
for(int i=0;i<m;i++)
{
tie(c,u,v)=g[i];
int tx=func(u);
int ty=func(v);
if(tx!=ty)
{
f[tx]=ty;
ans+=c;
if(++cnt==k-1)
break;
}
}
if(cnt==k-1)
cout<<ans<<endl;
else cout<<-1<<endl;
return 0;
}