zoukankan      html  css  js  c++  java
  • luoguP3959 [NOIP2017]宝藏(状压dp)

    www.cnblogs.com/shaokele/


    luoguP3959:[NOIP2017]宝藏##

      Time Limit: 1000 Sec
      Memory Limit: 256 MB
      p1
      p2
      p3
      p4
      p5
      

    题目地址:  luoguP3959:[NOIP2017]宝藏

    题目大意:

      选一个点作为根(起点),到达每一个节点
      
      (u)(v) 的代价为根到 (v) 的距离 (dis) 乘以 (u,v) 间距离 (w) ,求最小总代价

      

    题解:

      考试时没A 哭唧唧
      
      其实就是一个状态压缩啦
      
      具体看代码
      


    AC代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=15,M=5000,inf=10000000; 
    int n,m;
    int log[M],dis[N],p[N],g[M],f[M],mat[N][N],dp[N][M];
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=0;i<n;i++)
    		for(int j=0;j<n;j++)
    			mat[i][j]=inf;
    	for(int i=1;i<=m;i++){
    		int u,v,w;
    		scanf("%d%d%d",&u,&v,&w);
    		mat[--u][--v]=mat[v][u]=min(mat[u][v],w);
    	}
    	for(int i=0;i<n;i++)log[1<<i]=i;
    	memset(dp,0x3f,sizeof(dp));
    	for(int i=0;i<n;i++)dp[0][1<<i]=0;                               //dp[i][S]表示当前状态为S
    																	 //且最深节点到根节点距离为i的最小代价 
    	for(int i=0;i<n;i++){                                            //深度 
    		for(int S=0;S<(1<<n);S++){                                   //目前的状态 
    			int tot=0;                                               //记录下一次可以到达的点数 
    			for(int v=0;v<n;v++)                                     //下一步到达的点 
    				if(!(S & (1<<v))){
    					dis[tot]=inf;
    					p[tot]=1<<v;
    					for(int j=S;j;j-=j&(-j)){                        //寻找最短距离 
    						int u=log[j&(-j)];                           //可以出发的点 
    						dis[tot]=min(dis[tot],mat[u][v]*(i+1));      //记录到新节点的最短距离 
    					}
    					if(dis[tot]!=inf)tot++;
    				}
    			for(int j=1;j<(1<<tot);j++){                             //从1开始:至少要扩张一步 
    				g[j]=g[j-(j&(-j))]+dis[log[j&(-j)]];                 //加点的代价 
    				f[j]=f[j-(j&(-j))]|p[log[j&(-j)]];                   //新加的点 
    				dp[i+1][S|f[j]]=min(dp[i+1][S|f[j]],dp[i][S]+g[j]);  //转移 
    			}
    		}
    	}
    	int ans=1<<30;
    	for(int i=0;i<n;i++)											 //遍历深度统计答案 
    		ans=min(ans,dp[i][(1<<n)-1]);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    《跑跑跑》(五)——添加障碍物,Tiled障碍层的使用
    Cocos2d-JS 自定义loading界面
    Oracle本地,远程,分布式登录
    JUnit测试工具在项目中的用法
    js事件之神奇的onclick
    js常见事件
    JS & DOM 对象
    jquery方法的参数解读
    JDBC和DBUtils区别(查询时jdbc只能返回ResultSet需要po转vo,dbutils返回的BeanListHandler与BeanHandler对应集合与对象)
    AJAX技术的核心
  • 原文地址:https://www.cnblogs.com/shaokele/p/9163168.html
Copyright © 2011-2022 走看看