#include<bits/stdc++.h>
using namespace std;
struct node{
int x,y,w;
}a[100000]; //w是权值
using namespace std;
struct node{
int x,y,w;
}a[100000]; //w是权值
int f[100000];
bool cmp(node xx,node yy){
return xx.w<yy.w; //从小到大
}
return xx.w<yy.w; //从小到大
}
int find(int x)
{
if(x==f[x]) return x;
f[x]=find(f[x]);
return f[x]; //查找头上的节点,是不是在一个子图,
{
if(x==f[x]) return x;
f[x]=find(f[x]);
return f[x]; //查找头上的节点,是不是在一个子图,
int main() //后面基本就例题了
{
int n,k,m=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
f[i]=i;
for(int j=1;j<=n;j++)
{
scanf("%d",&k);
if(j>i)
{
m++;
a[m].x=i;a[m].y=j;a[m].w=k;
}
}
}
sort(a+1,a+m+1,cmp);
int ans=0,p=1;
for(int i=1;i<=m;i++)
{
if(find(a[i].x)!=find(a[i].y))
{
ans+=a[i].w;
f[find(a[i].x)]=a[i].y;
p++;
if(p==n) break;
}
}
cout<<ans<<endl;
return 0;
}
{
int n,k,m=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
f[i]=i;
for(int j=1;j<=n;j++)
{
scanf("%d",&k);
if(j>i)
{
m++;
a[m].x=i;a[m].y=j;a[m].w=k;
}
}
}
sort(a+1,a+m+1,cmp);
int ans=0,p=1;
for(int i=1;i<=m;i++)
{
if(find(a[i].x)!=find(a[i].y))
{
ans+=a[i].w;
f[find(a[i].x)]=a[i].y;
p++;
if(p==n) break;
}
}
cout<<ans<<endl;
return 0;
}