codevs 2596 状丫!

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

Input Description
村庄数n和各村之间的路程(均是整数)
输出描述 Output Description
最短的路程
样例输入 Sample Input
3
0 2 1
1 0 2
2 1 0
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
本题可用最短路思想、搜索来解决,但是可能无法通过一组极限数据(且效率较低)。建议按树状DP考虑!

分析:

不会的树上的dp啊,搜索又好像过不了,只能打状丫了
定义状态:f[i][j] i点j时的情况
状丫中的基础题

Code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int INF=0x3f3f3f,Maxm=(1<<15)+10,Maxn=15+10;
int n,ans=INF,map[Maxn][Maxn],f[Maxn][Maxm];
int main(){
    scanf("%d",&n);
    fo(i,1,n) 
        fo(j,1,n) scanf("%d",&map[i][j]);
    memset(f,63,sizeof(f));
    f[1][1]=0;
    fo(i,1,(1<<n)-1)
    {
        fo(j,1,n)
        {
            if(i&(1<<(j-1)))
            {
                fo(k,1,n)
                {
                    if(!(i&(1<<(k-1))))
                    {   
                        //此时j点访问过而k点并没有访问过
                        //所以要得到访问过k点就等于k到j的值 
                        f[k][i|(1<<(k-1))]=min(f[k][i|(1<<(k-1))],f[j][i]+map[j][k]);
                    }
                }
            }
        }
    }
    fo(i,1,n)
        ans=min(ans,f[i][(1<<(n))-1]+map[i][1]);
    printf("%d",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值