完全就是一道不带拐弯的minimum spanning tree,prim或kruskal都可以,这里我选择了kruskal。
以并查集1中的麦田数目是否等于麦田总数作为循环跳出条件。
#include <iostream>//考虑用set,但是需要重载运算符,不如用vector算了
#include <vector>
#include <algorithm>
using namespace std;
struct ROAD{
int vt1,vt2;
int cost;
};
bool cmp(ROAD a,ROAD b){
return a.cost<b.cost;
}
int order=1;
vector<int> flag(1001);
vector<ROAD> r;
int main(){
int n,m;
cin>>n>>m;
while (m--){
ROAD d;
int v1,v2,c;
scanf ("%d%d%d",&v1,&v2,&c);
d.vt1=v1;
d.vt2=v2;
d.cost=c;
r.push_back(d);
}
sort(r.begin(),r.end(),cmp);
long long ttcost=0;
int f=0;
auto pos=r.begin();
while (f<n){
if (!flag[pos->vt1]&&!flag[pos->vt2]){
ttcost+=pos->cost;
if (order==1) f+=2;
flag[pos->vt1]=flag[pos->vt2]=order;
order++;
}
else if (!flag[pos->vt1]){
ttcost+=pos->cost;
flag[pos->vt1]=flag[pos->vt2];
if (flag[pos->vt2]==1) f++;
}
else if (!flag[pos->vt2]){
ttcost+=pos->cost;
flag[pos->vt2]=flag[pos->vt1];
if (flag[pos->vt2]==1) f++;
}
else if(flag[pos->vt1]!=flag[pos->vt2]){
ttcost+=pos->cost;
bool hasone=false;
int change;
int needchange;
if (flag[pos->vt1]==1||flag[pos->vt2]==1){
change=1;
flag[pos->vt1]==1 ? needchange=flag[pos->vt2] : needchange=flag[pos->vt1];
hasone=true;
}
else {
change=flag[pos->vt1];
needchange=flag[pos->vt2];
}
if (hasone){
for (int i=1;i<=n;i++){
if (flag[i]==needchange) {
flag[i]=change;
f++;
}
}
}
else
for (int i=1;i<=n;i++){
if (flag[i]==needchange) {
flag[i]=change;
}
}
}
pos++;
}
printf ("%lld",ttcost);
}