zoukankan      html  css  js  c++  java
  • P1171 售货员的难题--搜索(剪枝)

    题目背景

    数据有更改

    题目描述

    某乡有nn个村庄(1<n le 201<n20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)s(0<s<1000)是已知的,且AA村到BB村与BB村到AA村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为11,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。

    输入输出格式

    输入格式:

    村庄数nn和各村之间的路程(均是整数)。

    输出格式:

    最短的路程。

    输入输出样例

    输入样例#1: 复制
    3
    0 2 1
    1 0 2
    2 1 0
    输出样例#1: 复制
    3


    ------------------------------------------------------------
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct pd
    {
        int ha,e;
    }lxy[25][25];
    //存图,ha表示各点时间消耗,e表示要去的点,因为排序动列,不动行,所以记下列,就是要去的点
    int hrb[25],n,i,j,k,minn=1e9,maxn=1001,emm[25];//新增一个emm数组解决排序动列的问题
    int cmp(pd a,pd b)
    {
        return a.ha<b.ha;
    }//排序函数
    int ss(int x,int y,int z) //y记录走过的村庄数 
    {
        if(z>=minn)
            return 0;//用sort优化,提前找出最小值,剪枝
        if(z+n-y+1+maxn>=minn)//两地之间距离最短是1 
            return 0//预见性剪枝,maxn表示x点到1的最小距离,然后剩余点取最小值1,极值判定
        if(y==n)
        {
            minn=min(minn,z+emm[x]);
            return 0;
        }
        if(y<n)
        for(int i=2;i<=n;i++)
        if(hrb[lxy[x][i].e]==0)
        //判断是否走过,为啥是lxy[x][i].e,请见上面解释
        {   
            if(z+lxy[x][i].ha+n-y+maxn>minn)
                return 0;
            //预见性剪枝,极值判定,用这两个可以90分
            hrb[lxy[x][i].e]=1;
            ss(lxy[x][i].e,y+1,z+lxy[x][i].ha);
            hrb[lxy[x][i].e]=0;
        }
        return 0;
    }
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {    
            for(k=1;k<=n;k++)
            {
                scanf("%d",&lxy[i][k].ha);
                lxy[i][k].e=k;//记录列数
                if(i!=1&&k==1)
                maxn=min(maxn,lxy[i][1].ha),emm[i]=lxy[i][1].ha;
     //求x到1的最小时间花费,用于预见性剪枝,和存x到1的花费用于搜索结算,解决排序造成的列乱序的情况
            }
            sort(lxy[i]+1,lxy[i]+n+1,cmp);
            //STL大法好,二维数组的排序要用for,sort可以优化找出的答案minn,减少无用功
        }
        hrb[1]=1;//跑过了就要踩,不然会跑回去,想想80分代码为啥不用赋值为1?因为80分列没乱序
        ss(1,1,0);
        printf("%d",minn);
        return 0;
    }

    这道题吧

    标签上是搜索

    然而

    大部分都是状压dp

    但还好

    还有写搜索的

    (我坚持写搜索的原因就是我搜索不太好)

    虽然草草的写了一个

    还过了样例

    但全wa了

    庆幸了一小下

    没有tle mle什么的

    但当我不太会改的时候

    才知道我的搜索是totally错的

    向现实低头的我

    有卑微看题解了

    (题解都在代码中)

  • 相关阅读:
    IOS Charles(代理服务器软件,可以用来拦截网络请求)
    Javascript中addEventListener和attachEvent的区别
    MVC中实现Area几种方法
    Entity Framework Code First 中使用 Fluent API 笔记。
    自定义JsonResult解决 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    An entity object cannot be referenced by multiple instances of IEntityChangeTracker 的解决方案
    Code First :使用Entity. Framework编程(8) ----转发 收藏
    Code First :使用Entity. Framework编程(6) ----转发 收藏
    Code First :使用Entity. Framework编程(5) ----转发 收藏
  • 原文地址:https://www.cnblogs.com/darlingroot/p/10346901.html
Copyright © 2011-2022 走看看