這道題的解法居然是最小生成樹,根本看不出來啊,果然圖論難就難在你根本看不出來它是圖論。
把同類元素的試劑當作一個點之後,把花費的腦力作爲邊權,求這個圖的最小生成樹即可。
人盡皆知求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;
}