UVa 216 网络连线

来源:互联网 发布:修改歌曲信息软件 编辑:程序博客网 时间:2024/05/18 13:24

题意:给出一些电脑的二维坐标,连接两个电脑所用网线长为它们之间的直线距离再加上16 feet。要求把所有电脑连成一个串,怎样连,使得所用网线最短,并且按从一端到另一端的顺序输出连接的两个电脑间的距离。

思路:很容易想到的就是暴力枚举,将所有电脑做一个全排列,求得总长最小值的那个。这里用的递归枚举、即回溯法,进行了剪枝优化。

第一次交WA了,重读题目、看别人题解,都没找到原因。看到别人的freopen,才发现我交的里面freopen没注释掉~

Code:

#include<stdio.h>#include<math.h>void solve(int n,int *A,int cur,double dist);int comp[10][2];int A[10];//排列 double C[10];//相邻两点间距离 int bestA[10];double bestC[10];double bestdist;int main(){  //freopen("216.in","r",stdin);  //freopen("216.out","w",stdout);      int n;  int num=1;  while(scanf("%d",&n)==1 && n)  {    for(int i=0;i<n;++i)      scanf("%d%d",&comp[i][0],&comp[i][1]);    bestdist=1000000000;    double dist=0;    solve(n,A,0,dist);    printf("**********************************************************\n");    printf("Network #%d\n",num++);    for(int i=0;i<n-1;++i)      printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2lf feet.\n"        ,comp[bestA[i]][0],comp[bestA[i]][1],comp[bestA[i+1]][0],comp[bestA[i+1]][1],bestC[i]);    printf("Number of feet of cable required is %.2lf.\n",bestdist);  }  return 0;}void solve(int n,int *A,int cur,double dist){  if(cur==n && dist<bestdist)  {    bestdist=dist;    for(int i=0;i<n-1;++i)      { bestC[i]=C[i]; bestA[i]=A[i]; }    bestA[n-1]=A[n-1];  }  else  for(int i=0;i<n;++i)  {    int ok=1;    for(int j=0;j<cur;++j) if(A[j]==i) { ok=0; break; }    if(ok)    {      A[cur]=i;      if(cur)      {        int dx=comp[A[cur]][0]-comp[A[cur-1]][0];        int dy=comp[A[cur]][1]-comp[A[cur-1]][1];        double jl=16+sqrt(dx*dx+dy*dy);        C[cur-1]=jl;        dist=dist+jl;        if(jl<bestdist && dist<bestdist) solve(n,A,cur+1,dist);        dist=dist-jl;//不要忘了这里的恢复。对枚举的每个i来说,dist应该是相同的。每一次i过来时,改变了dist的值,枚举下一个i时,应该把dist恢复。       }      else solve(n,A,cur+1,dist);//不要忘了这个     }        }}


0 0
原创粉丝点击