题目链接:https://ac.nowcoder.com/acm/contest/330/G
题意有点绕,但读懂以后其实就是一个最小生成树。让每个试剂作为结点,然后建边就好了,要严格要求xx要等于k,xx大于k也是不行的...
AC代码:
#include <bits/stdc++.h>
#define maxn 100005
#define ll long long
using namespace std;
struct Node{
int x,y;
ll w;
bool operator < (const Node &a)const{
return a.w > w;
}
}Edge[maxn];
int a[maxn],pre[maxn];
int n,m,k,num;
void init(){
for(int i=0;i<=k;i++){
pre[i] = i;
}
num = 0;
}
void add(int u,int v,ll w){
Edge[num].x = u;
Edge[num].y = v;
Edge[num++].w = w;
}
int Find(int x){
if(x != pre[x]){
pre[x] = Find(pre[x]);
}
return pre[x];
}
ll Kruskal(){
ll xx = 1;
ll sum = 0;
sort(Edge, Edge + num);
for(int i=0;i<num;i++){
int fx = Find(Edge[i].x);
int fy = Find(Edge[i].y);
if(fx != fy){
pre[fy] = fx;
xx ++;
sum += Edge[i].w;
}
}
return xx == k ? sum : -1;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
init();
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=0;i<m;i++){
int u, v;
ll w;
scanf("%d%d%lld",&u, &v, &w);
add(a[u], a[v], w);
}
ll ans = Kruskal();
printf("%lld\n", ans);
return 0;
}