题意:不解释了
思路:也不解释了,并查集判段连通性,Kruskal求最小生成树,大水题(/ □ \)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=110;
struct edge{
int u,v,cost;
};
edge es[maxn];
bool cmp(const edge &a,const edge &b){
return a.cost<b.cost;
}
int V,E;
int f[maxn];
int find1(int x){
if(x!=f[x]) f[x]=find1(f[x]);
return f[x];
}
void unite(int a,int b){
int aa=find1(a);
int bb=find1(b);
if(aa==bb) return ;
f[aa]=bb;
}
int kruskal(){
sort(es,es+E,cmp);
for(int i=0;i<=V;i++) f[i]=i;
int res=0;
for(int i=0;i<E;i++){
edge e=es[i];
if(find1(e.u)!=find1(e.v)){
unite(e.u,e.v);
res+=e.cost;
}
}
return res;
}
int main(){
int u,v,cost;
while(scanf("%d%d",&E,&V)!=1){
if(E==0) break;
for(int i=0;i<=V;i++) f[i]=i;
int sum=0,k=0;
for(int i=0;i<E;i++){
scanf("%d%d%d",&u,&v,&cost);
es[k].u=u;es[k].v=v;es[k++].cost=cost;
if(find1(u)!=find1(v)){
unite(u,v);sum++;
}
}
if(sum!=V-1) printf("?\n");
else{
printf("%d\n",kruskal());
}
}
return 0;
}