优化:先排序,再去重。
ACcode:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int NS=20;
const double INF=1000000000.0;
const double eps=1e-8;
struct Point
{
double d,x,y;
bool operator < (const Point cmp)const {
return d<cmp.d;
}
}p[NS],beg;
int n,top,lim,p2[NS+1];
double res;
double dp[1<<NS],g[NS][NS];
double Dist(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double Cal(Point a,Point b,Point c)
{
return Dist(a,b)+Dist(b,c);
}
double dfs(int st,int pos)
{
if (dp[st]<INF) return dp[st];
for (pos=0;(p2[pos]&st)==0;pos++);
for (int i=pos+1;i<top;i++)
{
if ((p2[i]&st))
{
int t=st-p2[pos]-p2[i];
dp[st]=min(dp[st],dfs(t,pos+1)+p[pos].d+g[i][pos]);
}
}
return dp[st];
}
int main()
{
p2[0]=1;
for (int i=1;i<=NS;i++)
p2[i]=p2[i-1]<<1;
int T,cas=0;
scanf("%d",&T);
while (T--)
{
scanf("%lf%lf",&beg.x,&beg.y);
scanf("%d",&n),top=n+n;
for (int i=0;i<top;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
p[i].d=Dist(beg,p[i]);
}
sort(p,p+top);
for (int i=0;i<top;i++)
for (int j=0;j<=i;j++)
g[i][j]=g[j][i]=Dist(p[i],p[j]);
lim=(1<<top)-1,res=INF;
for (int i=1;i<=lim;i++)
dp[i]=INF;
dp[0]=0.0;
dfs(lim,0);
/*
int pos=0;
for (int i=0;i<=lim;i++)
{
if (dp[i]>=INF) continue;
int x,y;
for (x=0;(p2[x]&i)&&x<top;x++);
for (int j=x+1;j<top;j++)
if (!(p2[j]&i))
{
y=i|p2[x]|p2[j];
dp[y]=min(dp[y],dp[i]+p[x].d+g[x][j]);
}
}
*/
printf("Case #%d: %.2lf\n",++cas,dp[lim]);
}
return 0;
}