宝藏noip2017day2t2--状态压缩

完成状态的最优值,数据范围<=16优先考虑状态压缩。

枚举每个起点,从这个点开始求总路径,难点就在记录路径的长度。,如果经过一个转移点,路径长度+1,其他的点没有经过,保持原来的值。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
const int maxn=17,inf=0x3f3f3f3f;
int map[maxn][maxn],step[maxn][maxn],num,n,m,nums;
int f[1<<16],cs[maxn][1<<16];

int dp(int s){
    memset(f,0x3f,sizeof(f));
    nums=(1<<n)-1;	
    f[1<<(s-1)]=0; cs[s][(1<<(s-1))]=0;
    for(int i=0;i<=nums;i++)//枚举所有可能的状态;
        for(int j=1;j<=n;j++)
            if(i&(1<<(j-1))) //枚举当前状态下到了第j个结点 
                for(int k=1;k<=n;k++) {//从j之k,找出到k的最优值。 
                    if((i&(1<<(k-1)))==0&&map[j][k]<inf){ //如果第k结点还到,那么到达k,并更新其值。
                  		int p=1<<(k-1);
                  		int x=f[i]+(cs[j][i]+1)*map[j][k];
                  		if(f[i|p]>x){
                  			f[i|p]=x;
                  			for(int l=1;l<=n;l++)cs[l][i|p]=cs[l][i];//原来的没经过j到 
                            cs[k][i|p]=cs[j][i]+1;//k点经过j点到达,步数增加 
                        }
                    }
                }
    return f[nums];
}
int main(){
    
    memset(map,63,sizeof(map));
    cin>>n>>m;	
    int u,v,x;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&x);
        map[u][v]=min(map[u][v],x);
        map[v][u]=map[u][v]; 
        }
    int ans=0x3f3f3f3f;
    for(int i=1;i<=n;i++)
        ans=min(ans,dp(i));	
    cout<<ans<<endl;				
    return 0;	
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值