题意:给出n个点的坐标,(2<=n<=8),现在要使得这n个点连通,问最小的距离的和
因为n很小,所以可以直接枚举这n个数的排列,算每一个排列的距离的和,
保留下距离和最小的那个排列就可以了(这个地方和带宽那题有点像,用memcpy将整个排列保留下来)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 using namespace std; 12 13 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i) 14 15 typedef long long LL; 16 const int INF = (1<<30)-1; 17 const int mod=1000000007; 18 const int maxn=100005; 19 20 int p[maxn],bestp[maxn]; 21 22 struct node{ 23 int x,y; 24 } a[maxn]; 25 26 double dis(int x1,int y1,int x2,int y2){ 27 return sqrt((double)(x2 - x1) * (x2 - x1) +(double) (y2 - y1) * (y2 - y1)); 28 } 29 30 int main(){ 31 // freopen("in.txt","r",stdin); 32 // freopen("out.txt","w",stdout); 33 int n; 34 double ans,minn=0; 35 int kase=0; 36 while(scanf("%d",&n)!=EOF&&n){ 37 for(int i=0;i<n;i++) { 38 cin>>a[i].x>>a[i].y; 39 if(i!=0) minn+=dis(a[i].x,a[i].y,a[i-1].x,a[i-1].y); 40 } 41 42 for(int i=0;i<n;i++) p[i]=i; 43 memcpy(bestp,p,sizeof(p)); 44 45 46 while(next_permutation(p,p+n)){ 47 ans=0; 48 for(int i=1;i<n;i++) 49 ans+=dis(a[p[i]].x,a[p[i]].y,a[p[i-1]].x,a[p[i-1]].y); 50 51 // printf("ans=%lf\n",ans); 52 53 if(ans<minn){ 54 minn=ans; 55 memcpy(bestp,p,sizeof(p)); 56 } 57 } 58 59 printf("**********************************************************\n"); 60 printf("Network #%d\n",++kase); 61 for(int i = 1; i < n; ++i) 62 printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2lf feet.\n",(int)a[bestp[i-1]].x, 63 (int)a[bestp[i-1]].y,(int)a[bestp[i]].x,(int)a[bestp[i]].y,16.0 + dis(a[bestp[i-1]].x,a[bestp[i-1]].y,a[bestp[i]].x,a[bestp[i]].y)); 64 printf("Number of feet of cable required is %.2lf.\n",minn + (n - 1) * 16.0); 65 } 66 return 0; 67 }
时间: 2024-10-05 18:39:49