hash+置换群
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h>
#include<string.h>
int a[10009];
int hash[100009];
bool use[100009];
int min1(int a,int b)
{
if(a>b)return b;
else
return a;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i,min=9999999,max=0;
memset(hash,0,sizeof(hash));
memset(use,0,sizeof(use));
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]<min)min=a[i];
if(max<a[i])max=a[i];
hash[a[i]]=1;
use[a[i]]=1;
}
int add=1;//放入hash
for(i=1;i<=max;i++)
{
if(hash[i]==1)
{
hash[i]=a[add];
add++;
}
}
int all=0,j;
int sum1,sum2,sum,tmin;
for(i=1;i<=max;i++)
{
if(hash[i]==i||use[i]==0)continue;
j=i;
sum1=0,sum2=0,sum=0,tmin=j;
use[j]=0;
add=1;
sum+=j;
while(use[hash[j]]==1)
{
j=hash[j];
use[j]=0;
if(tmin>j)tmin=j;
sum+=j;
add++;
}
sum1=sum+(add-2)*tmin;
sum2=sum+tmin+(add+1)*min;
all+=min1(sum1,sum2);
}
printf("%d\n",all);
}
}