数据范围小地可怜
那就模拟退火
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int ans[50];
int son[50][5];
int n;
int tem[50];
int x,y,z;
double delat=0.996;
int anss;
int cal(){
int ans=0;
for(int i=1;i<=n;++i){
ans+=abs(tem[i]-tem[son[i][0]]) +abs(tem[i]-tem[son[i][2]])+abs(tem[i]-tem[son[i][1]]);
}
return ans;
}
void sa(){
for(int i=1;i<=n;++i){
tem[i]=ans[i];
}
double t=2000;
int temm=anss;
while(t>=1e-15){
int nx=rand()%n+1;
int ny=rand()%n+1;
if(nx==ny) continue;
swap(tem[nx],tem[ny]);
int res=cal();
int rres=res-temm;
if(rres<0){
for(int i=1;i<=n;++i)
ans[i]=tem[i];
anss=temm=res;
}else{
if(exp(-rres/t)*RAND_MAX<rand())
swap(tem[nx],tem[ny]);
else{
temm=res;
}
}
t*=delat;
}
}
int main(){
srand(20040519);
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d%d%d",&son[i][0],&son[i][1],&son[i][2]);
ans[i]=tem[i]=i;
}
anss=cal();
sa();
sa();
sa();
cout<<anss/2<<endl;
return 0;
}