zoukankan      html  css  js  c++  java
  • 洛谷P1171 售货员的难题

    P1171 售货员的难题

    题目背景

    数据有更改

    题目描述

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

    输入输出格式

    输入格式:

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

    输出格式:

    最短的路程。

    输入输出样例

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

    说明

    输入解释

    3 {村庄数}

    0 2 1 {村庄1到各村的路程}

    1 0 2 {村庄2到各村的路程}

    2 1 0 {村庄3到各村的路程}

    /*
        洛谷上只能到90分qwq
    */
    #include<iostream>
    #include<cstdio>
    #define maxn 20
    int n,num,head[maxn],ans=0x7fffffff;
    struct node{
        int to,pre,v;
    }e[maxn*maxn];
    bool vis[maxn];
    using namespace std;
    void Insert(int from,int to,int v){
        e[++num].to=to;
        e[num].v=v;
        e[num].pre=head[from];
        head[from]=num;
    }
    void dfs(int pos,int cnt,int dis){
        if(dis>=ans)return;
        if(dis+n-cnt+1>=ans)return;
        for(int i=head[pos];i;i=e[i].pre){
            int to=e[i].to;
            if(to==1&&cnt==n){
                ans=min(ans,dis+e[i].v);
                return;
            }
            if(vis[to])continue;
            vis[to]=1;
            dfs(to,cnt+1,dis+e[i].v);
            vis[to]=0;
        }
    }
    int qread(){
        int i=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();}
        return i;
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        n=qread();
        int x;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                x=qread();
                if(i!=j)Insert(i,j,x);
            }
        vis[1]=1;
        dfs(1,1,0);
        printf("%d",ans);
    }
    90分 搜索+剪枝
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,map[21][21],all,dp[21][1<<20],ans=0x7fffffff;
    int qread(){
        int i=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();}
        return i;
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        //scanf("%d",&n);
        n=qread();
        all=(1<<n)-1;
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)map[i][j]=qread();
        memset(dp,0x3f,sizeof(dp));
        dp[0][0]=0;
        for(int i=1;i<=n;i++)dp[i][1<<(i-1)]=map[1][i];
        for(int s=0;s<=all;s++){
            for(int i=1;i<=n;i++)
                if(s&(1<<(i-1)))
                    for(int j=1;j<=n;j++)
                        dp[i][s]=min(dp[i][s],dp[j][s^(1<<(i-1))]+map[j][i]);
        }
        for(int i=1;i<=n;i++)ans=min(ans,dp[i][all]+map[i][1]);
        printf("%d",ans);
    }
    80分 状压+枚举
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define min(a,b) (a)>(b)?(b):(a)
    int n,map[21][21],all,dp[21][1<<20],ans=0x7fffffff,bit[21];
    int qread(){
        int i=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();}
        return i;
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        //scanf("%d",&n);
        bit[1]=1;
        for(int i=2;i<=20;i++)bit[i]=bit[i-1]<<1;
        n=qread();
        all=(1<<n)-1;
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)map[i][j]=qread();
        memset(dp,0x3f,sizeof(dp));
        dp[1][1]=0;
        for(int s=1;s<=all;s+=2){
            for(int i=1;i<=n;i++)
                if(dp[i][s]<=30000)
                    for(int j=1;j<=n;j++)
                    if(!(s&bit[j]))
                        dp[j][s|bit[j]]=min(dp[j][s|bit[j]],dp[i][s]+map[i][j]);
        }
        for(int i=1;i<=n;i++)ans=min(ans,dp[i][all]+map[i][1]);
        printf("%d",ans);
    }
    100分 状压
  • 相关阅读:
    loadOnStartup = 1
    TP复习8
    TP复习7
    TP复习6
    TP复习5
    TP复习4
    TP复习3
    TP复习2
    TP复习
    document.createElement("A");
  • 原文地址:https://www.cnblogs.com/thmyl/p/7724578.html
Copyright © 2011-2022 走看看