UVA 216(Getting in Line)回溯

本文探讨了UVA-216题目中寻找连接所有点的最短路径的问题,通过两种不同的方法实现:回溯法与全排列法,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给出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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值