洛谷 P3959 NOIP2017 宝藏 —— 状压搜索

题目:https://www.luogu.org/problemnew/show/P3959

搜索;

不是记忆化,而是剪枝;

邻接矩阵存边即可,因为显然没有那么多边。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll const inf=0x3f3f3f3f3f3f3f3f;
int n,m,S,sid[20][20];
ll s[1<<13],ans,dis[20];
ll dfs(int p,ll w)
{
    if(w>=ans)return inf;
    if(p==S)return w;
//    if(s[p])return s[p];//错误记忆化 
    s[p]=min(s[p],w);//
    ll ret=inf;
    for(int x=1;x<=n;x++)
    {
        if((p&(1<<(x-1)))==0)continue;
        for(int u=1;u<=n;u++)    if(sid[x][u]!=inf&&((1<<(u-1))&p)==0)
        {
            int np=(p|(1<<(u-1)));
            if(s[np]<=w+sid[x][u]*(dis[x]+1))continue;//最优性剪枝 
            dis[u]=dis[x]+1;
            ret=min(ret,dfs(np,w+sid[x][u]*dis[u]));
            dis[u]=0;
        }
    }
    return ret;
}
int main()
{
    scanf("%d%d",&n,&m);
    memset(sid,0x3f,sizeof sid);
    for(int i=1,x,y,z;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        sid[x][y]=min(sid[x][y],z);
        sid[y][x]=sid[x][y];
    }
    ans=inf; S=(1<<n)-1;
    for(int i=1;i<=n;i++)
    {
        memset(s,0x3f,sizeof s);
        ans=min(ans,dfs(1<<(i-1),0));
    }
    printf("%lld\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/Zinn/p/9375800.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值