poj 2280 Islands and Bridges 哈密尔顿路 状压dp
题目链接
题意
给定一个\(N\)个点的无向图,求一条哈密尔顿路径\(C_1C_2...C_n\),使其\(value\)最大。
\(value\)的计算方式如下:$$\begin{aligned}value&=\sum_{i=1}{n}C_i\&+\sum_{i=1}{n-1}C_iC_{i+1}\&+\sum_{i=1}^{n-2}C_iC_{i+1}*C_{i+2}[(C_i,C_{i+2})is\ an\ edge\ in\ the\ graph]\end{aligned}$$
思路
状态表示及转移等与前两题相类似。
因为状态和前两步相关,所以用\(dp[state][i][j]\)表示,接连经过\(j\)点与\(i\)点到达\(state\)状态的最大\(value\)值和对应的路径数目。
注意答案会爆\(int\).
Code
#include <cstdio>
#include <iostream>
#include <cstring>
#define maxn 10010
#define inf 0x3f3f3f3f
#define F(i, a, b) for (LL i = (a); i < (b); ++i)
#define F2(i, a, b) for (LL i = (a); i <= (b); ++i)
#define dF(i, a, b) for (LL i = (a); i > (b); --i)
#define dF2(i, a, b) for (LL i = (a); i >= (b); --i)
using namespace std;
bool vis[maxn][13][13], dis[13][13];
typedef long long LL;
LL v[13], n, m;
struct node { LL v, w, flag; }dp[maxn][13][13];
node dfs(LL state, LL p1, LL p2) {
if (state==(1<<p1)+(1<<p2)) return {v[p1]+v[p2]+v[p1]*v[p2], 1, 1};
if (vis[state][p1][p2]) return dp[state][p1][p2];
vis[state][p1][p2] = true;
LL sta = state - (1<<p1);
node ans = {0, 0, 0};
bool flag = false;
F(i, 0, n) {
if (i==p1 || i==p2 || !dis[i][p2] || !(state&(1<<i))) continue;
node nd = dfs(sta, p2, i);
if (!nd.flag) continue;
flag = true;
LL temp = nd.v + (dis[p1][i]?v[p1]*v[p2]*v[i]:0);
if (temp > ans.v) ans = {temp, nd.w};
else if (temp == ans.v) ans.w += nd.w;
}
if (!flag) return dp[state][p1][p2] = {0, 0, 0};
else return dp[state][p1][p2] = {ans.v + v[p1] + v[p1]*v[p2], ans.w, 1};
}
void work() {
memset(dis, 0, sizeof dis);
memset(vis, 0, sizeof vis);
memset(dp, 0, sizeof dp);
scanf("%lld%lld", &n, &m);
F(i, 0, n) scanf("%lld", &v[i]);
F(i, 0, m) {
LL u, v;
scanf("%lld%lld", &u, &v); --u, --v;
dis[u][v] = dis[v][u] = 1;
}
if (n==1) { printf("%lld %lld\n", v[0], 1); return; }
node ans = {0, 0, 0};
F(i, 0, n) {
F(j, 0, n) {
if (i==j || !dis[j][i]) continue;
node temp = dfs((1<<n)-1, i, j);
if (!temp.flag) continue;
if (temp.v > ans.v) ans = temp;
else if (temp.v == ans.v) ans.w += temp.w;
}
}
printf("%lld %lld\n", ans.v, ans.w>>1);
}
int main() {
LL T;
scanf("%lld", &T);
while (T--) work();
return 0;
}
poj 2280 Islands and Bridges 哈密尔顿路 状压dp的更多相关文章
- POJ 3254 Corn Fields:网格密铺类 状压dp
题目链接:http://poj.org/problem?id=3254 题意: 给你一片n*m的耕地,你可以在上面种玉米.但是其中有一些地方是荒芜的,不能种植.并且种植玉米的地方不能相邻.问你在这片地 ...
- Islands and Bridges(POJ2288+状压dp+Hamilton 回路)
题目链接:http://poj.org/problem?id=2288 题目: 题意:求Hamilton 路径权值的最大值,且求出有多少条权值这么大的Hamilton路径. 思路:状压dp,dp[i] ...
- CH0103最短Hamilton路径 & poj2288 Islands and Brigdes【状压DP】
虐狗宝典学习笔记: 取出整数\(n\)在二进制表示下的第\(k\)位 \((n >> ...
- POJ 1185 炮兵阵地(状压DP)
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26426 Accepted: 10185 Descriptio ...
- POJ 3254 Corn Fields (状压dp)
题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...
- POJ 2411 Mondriaan's Dream -- 状压DP
题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...
- POJ 3254 - Corn Fields - [状压DP水题]
题目链接:http://poj.org/problem?id=3254 Time Limit: 2000MS Memory Limit: 65536K Description Farmer John ...
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
[题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...
- poj 2288 Islands and Bridges ——状压DP
题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...
随机推荐
- 十一、Shell 输入/输出重定向
Shell 输入/输出重定向 大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端.一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端.同样,一个命令 ...
- awk截取指定字段
#!/bin/bash #好多地方可以优化,先记录下,便于以后使用 dir="/logs/$1"file="/logs/$1/requests.log"if [ ...
- DevOps - CI/CD - Jenkins
Jenkins 是一款流行的开源持续集成(Continuous Integration)工具,广泛用于项目开发,具有自动化构建.测试和部署等功能.本文以 CentOS7 环境为例,总结了 Jenkin ...
- php扩展开发-实现一个简易的哈希表
从一个简易的哈希表入手,会让你更好的理解php的哈希表,他们的本质是一样的,只是php的哈希表做了更多的功能扩展,php的哈希表是php语言的一个重要核心,大量的内核代码使用到哈希表. #includ ...
- kafka及扩展的安装笔记
参考文件 https://blog.csdn.net/weiwenjuan0923/article/details/76152744 一.首先确认下jdk有没有安装 安装参照这个连接 https:// ...
- python 3 在工作中的应用
Python 3在工作中的使用 安装配置Python 3 在notepad++中配置Python 3 使用sql server数据库 操作Excel 发送email python 3 使用日志 安 ...
- 科学计算库Numpy——数组生成
等差数组 使用np.arange()或np.linspace()生成元素是等差数列的数组. 以10为底的数组 使用np.logspace()生成元素是以10为底的数组. 数组扩展 使用np.meshg ...
- 三分钟明白 Activity工作流 -- java运用
一. 什么是工作流 以请假为例,现在大多数公司的请假流程是这样的 员工打电话(或网聊)向上级提出请假申请——上级口头同意——上级将请假记录下来——月底将请假记录上交公司——公司将请假录入电脑 采用工作 ...
- Elastic Search和Kibana入门
一.ES配置 二.ES本地快速搭建集群 查看ES集群 查看node详细情况 三.Kibana配置 修改kibana的es配置 访问localhost:5601端口 四.Elasticsearch 术语 ...
- privoxy+ss5实现 HTTP 代理协议转socks5代理
一.系统准备资源 二.ss5安装部署 1.SOCK5代理服务器部署环境准备 IP:10.0.0.100 官网: http://ss5.sourceforge.net/ 下载 yum - ...