#include <iostream>
#include <algorithm>
using namespace std;
template<typename T=int>
inline T read(){
T X=0; bool flag=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<1)+(X<<3)+ch-'0',ch=getchar();
if(flag) return X;
return ~(X-1);
}
template<typename T=int>
inline void write(T X){
if(X<0) putchar('-'),X=~(X-1);
T s[20],top=0;
while(X) s[++top]=X%10,X/=10;
if(!top) s[++top]=0;
while(top) putchar(s[top--]+'0');
putchar('\n');
}
const int N=105;
struct edge{
int u,v,w;
bool operator<(edge a){
return this->w<a.w;
}
}e[N*N];
int n,x,top;
template<class T=int>
class set{
public:
set(){
f=new T[N];
for(int i=0; i<N; i++){
f[i]=0;
}
}
~set(){
delete[] f;
}
T find(T x){
if(f[x]==x) return x;
else return f[x]=find(f[x]);
}
void merge(T x,T y){
f[find(x)]=find(y);
}
private:
T *f;
};
template<typename T=int>
T kruskal(int n,int m){
sort(e+1,e+m+1);
set s;
T ans=0;
int cnt=1;
for(int i=1; i<=m; i++){
if(s.find(e[i].u)!=s.find(e[i].v)){
ans+=e[i].w;
s.merge(e[i].u,e[i].v);
if(++cnt==n){
break;
}
}
}
return ans;
}
int main(){
n=read();
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
x=read();
if(j>i){
e[++top]=edge{i,j,x};
}
}
}
write(kruskal(n,top));
return 0;
}
样例输出 0 /kel,和第一篇题解 "差不多" 啊。。