题意:给出n个点,求n-1条路连接所有点,路径之和最短
注意:要在每条路的距离加上16(题目说的),刚开始想到的是用回溯,毕竟现在在做这个专题,要用一个数组记录路径!
回溯的代码玄学WA,找不到原因,求大神指教
#include<bits/stdc++.h>
#define LL long long
#define maxn 50010
using namespace std;
struct Point
{
int x,y;
} p[10];
double ans=0;
int n;
int vis[10];
int num[10],result[10];
double dis(Point p1,Point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))+16;
}
void dfs(long double sum,int cnt,int now)
{
if(cnt==n)
{
if(ans>sum)
{
ans=sum;
for(int i=1; i<=n; i++)
{
result[i]=num[i];
//cout<<p[num[i]].x<<' '<<p[num[i]].y<<endl;
}
//cout<<"///////////"<<endl;
}
}
else
{
for(int i=1; i<=n; i++)
{
if(!vis[i]&&i!=now)
{
vis[i]=1;
num[cnt+1]=i;
dfs(sum+dis(p[now],p[i]),cnt+1,i);
vis[i]=0;
num[cnt+1]=0;
}
}
}
}
int main()
{
int T=1;
//ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
while(cin>>n)
{
if(n==0)
{
//cout<<endl;
break;
}
ans=2147483646;
for(int i=1;i<=10;i++)
{
vis[i]=0;
}
for(int i=1; i<=n; i++)
{
cin>>p[i].x>>p[i].y;
}
for(int i=1; i<=n; i++)
{
vis[i]=1;
num[1]=i;
dfs(0,1,i);
vis[i]=0;
}
cout<<"**********************************************************"<<endl;
printf("Network #%d\n",T++);
//double sum=0;
for(int i=1; i<n; i++)
{
printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2f feet.\n",p[result[i]].x,p[result[i]].y,p[result[i+1]].x,p[result[i+1]].y,dis(p[result[i]],p[result[i+1]]));
//cout<<p[num[i]].x<<' '<<p[num[i]].y<<endl;
// sum+=dis(p[result[i]],p[result[i+1]]);
}
printf("Number of feet of cable required is %.2f.\n",ans);
// cout<<sum<<endl;
}
return 0;
}
看了一下其它博客,数据不大,可以直接用全排列……
引用一位学长的话:耍流氓!这一点也不优雅!
毕竟是作业……还是用这种方法做了
#include<bits/stdc++.h>
#define LL long long
#define maxn 50010
using namespace std;
struct Point
{
int x,y,num;
} p[10];
double ans=0;
int n;
int vis[10];
int num[10],result[10];
double dis(Point p1,Point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))+16;
}
void cal()
{
double temp=0;
for(int i=1;i<n;i++)
{
temp+=dis(p[num[i]],p[num[i+1]]);
}
if(temp<ans)
{
ans=temp;
for(int i=1;i<=n;i++)
{
result[i]=num[i];
}
}
}
int main()
{
int T=1;
//ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
while(cin>>n&&n)
{
for(int i=1; i<=n; i++)
{
cin>>p[i].x>>p[i].y;
num[i]=i;
}
ans=2147483646;
do
{
cal();
}while(next_permutation(num+1,num+n+1));
cout<<"**********************************************************"<<endl;
printf("Network #%d\n",T++);
//double sum=0;
for(int i=1; i<n; i++)
{
printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2f feet.\n",p[result[i]].x,p[result[i]].y,p[result[i+1]].x,p[result[i+1]].y,dis(p[result[i]],p[result[i+1]]));
//cout<<p[num[i]].x<<' '<<p[num[i]].y<<endl;
// sum+=dis(p[result[i]],p[result[i+1]]);
}
printf("Number of feet of cable required is %.2f.\n",ans);
// cout<<sum<<endl;
}
return 0;
}