hdu3001(三进制状压)
题目大意:
现在给你一个有n个点和m条边的图,每一条边都有一个费用,每个点不能经过超过两次,求所有点至少遍历一次的最小费用
其中n<=10 m没有明确限制(肯定不会超过1e5)
一看到这个数据范围,第一想法就是状压QWQ
但是转念一想,woc,每个点不一定只经过一次咯。
woc,那不就是三进制状压?!
好的,至此,这个题成功的成为了我人生中的第一道三进制状压
f[S][i]表示已经走过的点的集合是S 当前在i的最小费用
首先,我们要先预处理一个num数组
num[i][j]表示i这个数的三进制拆分的第j位是什么
void count()
{for (int i=0;i<=59049;i++){int cnt=i;for (int j=1;j<=10;j++)num[i][j]=cnt%3,cnt/=3;}
}
便于之后的计算
之后枚举状态
枚举当前点,枚举目标点,进行转移即可
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>using namespace std;inline int read()
{int x=0,f=1;char ch=getchar();while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;
}int f[100010][12];
int num[100010][12];
int n,m;
int a[20][20];
int ymh;
bool pp;int qsm(int i,int j)
{int ans=1;while (j){if (j&1) ans*=i;i=i*i;j>>=1;}return ans;
}void init()
{memset(f,127/3,sizeof(f));memset(a,-1,sizeof(a));
}void count()
{for (int i=0;i<=59049;i++){int cnt=i;for (int j=1;j<=10;j++)num[i][j]=cnt%3,cnt/=3;}
}int main()
{count();while (scanf("%d%d",&n,&m)!=EOF){init();int ans=1e9;pp=true; for (int i=1;i<=m;i++){int u,v,w;u=read();v=read();w=read();if (a[u][v]==-1){a[u][v]=w;}else a[u][v]=min(a[u][v],w);a[v][u]=a[u][v];}ymh=qsm(3,n)-1;//cout<<ymh<<endl;for (int i=1;i<=n;i++)f[qsm(3,i-1)][i]=0;for (int i=1;i<=ymh;i++){bool flag=true;for (int j=1;j<=n;j++){if (num[i][j]==0){flag=false;continue;}for (int k=1;k<=n;k++){if (a[j][k]!=-1 && num[i][k]<2 && k!=j){int kk=i+qsm(3,k-1);f[kk][k]=min(f[kk][k],f[i][j]+a[j][k]);}}}if (flag)for (int j=1;j<=n;j++)ans=min(ans,f[i][j]);}if (ans==f[100001][11]) ans=-1;cout<<ans<<endl;}return 0;
}
转载于:https://www.cnblogs.com/yimmortal/p/10160616.html
hdu3001(三进制状压)相关推荐
- HDU-3001(旅行商问题+三进制状压dp)
#include <bits/stdc++.h> using namespace std; /* 题目大意: 给定n个点m条边的带权无向图,问有没有可能从n个点的其中一个出发,走遍其余n ...
- HDU 3001 三进制状压DP
HDU 3001 三进制状压DP N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方 ...
- HDU 3001 Travelling (三进制状压dp)
题意 n(n<=10)n(n个城市,知道每个城市间的旅行费用,但每个城市最多走两遍.问最小花费是多少 . 也就是每个城市可以走两次的tsp问题. 分析 最多走两次,三进制0 1 2可满足,即用三 ...
- 涂抹果酱(三进制状压dp)
涂抹果酱(状压dp) 题目描述 输入描述: 输出描述: 示例 输入 输出 说明 备注: 题目思路: 代码 欢迎关注微信公众号:Java后台开发 题目描述 Tyvj两周年庆典要到了,Sam想为Tyvj做 ...
- 三进制状压动态规划【涂抹果酱】 题解
前言:好不容易搞懂了这道题,感觉网上能找到的题解在我有疑问的地方都讲的不是很细,所以我来写一篇吧. 题目描述 Tyvj 两周年庆典要到了,Sam 想为 Tyvj 做一个大蛋糕.蛋糕俯视图是一个 N×M ...
- Travelling (三进制+状压dp)
题目链接 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 inline ll rea ...
- HDU3001 Traveling (状压dp+三进制+Tsp问题总结)
(1)这道题最多可以走两次,所以有0, 1, 2三种状态,所以我们要用三进制 如果要用三进制,就要自己初始化两个数组, 一个是3的n次方,一个是三进制数的第几位的数字是什么 void init() { ...
- CF1556F-Sports Betting【状压dp,数学期望】
正题 题目链接:https://www.luogu.com.cn/problem/CF1556F 题目大意 nnn个点的一张竞赛图,每个点有一个权值aia_iai,(i,j)(i,j)(i,j)之间 ...
- 蒜头君救人 状压DP
蒜头君救人 题目描述 蒜头君是一个乐于助人的好孩子,这天他所在的乡村发生了洪水,有多名村民被困于孤岛上,于是蒜头君决定去背他们离开困境,假设蒜头君所在的村子是 n×m n×m 的网格,网格中.号代表平 ...
最新文章
- 问题解决: SSR 的 1080 端口被占用
- JavaScript调用WebServices
- Mac eclipse找不到source的解决办法
- qgis 图片_QGIS教程09QGIS中如何制作萤火虫地图?
- JavaScript 小技巧之数组合并
- 2015年蓝桥杯A组C/C++ 第三题奇妙的数字
- 技术分享PPT整理(一):Bootstrap基础与应用
- 金鳞化龙——AMD处理器“开核”大测试(图)
- 深圳市商务局2022年度中央资金(跨境电子商务企业市场开拓扶持事项)申报指南
- 向98年的华为学习:没有高管办公室的青铜器软件
- 官宣 | 首届云原生编程挑战赛报名通道正式开启
- android的平台签名工具,《安卓开发》APK签名工具使用方法
- java 滑杆和进度条_进度条 和 滑条
- PSPICE 仿真故障
- 2020计算机二级题库第14word,2020年新版全国计算机等级考试二级MSoffice选择题题库.docx...
- 入门必看!ui设计分类有哪些?【萧蕊冰】
- B端产品运营:获客渠道和方法
- 详解图像二值化 函数threshold
- python医疗影像_基于PyRadiomics的医疗影像纹理获取原型系统集成
- 湖北性能优良戴尔服务器,超高密度的1U机架 戴尔R630服务器评测
热门文章
- 用java怎么实现数据库_用Java实现数据库应用系统
- c# poi写入e_C# 使用 NPOI 库读写 Excel 文件(转载)
- android java 给控件设置style,在Android Lollipop for Material Design中为SwitchCompat按钮设置样式/着色...
- Linux下的静态链接库和动态链接库编程
- Linux下进行谷歌浏览器安装
- 开发日记-20190527 关键词 ubuntu无线网卡驱动安装
- mongodb 新增字段
- An attempt has been made to start a new process before the current process has finished its
- Fastadmin 写关联命名时,最好前后台用同一个model,方便管理(会出现命名空间问题)...
- myapp——自动生成小学四则运算题目的命令行程序(侯国鑫 谢嘉帆)