题目链接

题意

给定一个\(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的更多相关文章

  1. POJ 3254 Corn Fields:网格密铺类 状压dp

    题目链接:http://poj.org/problem?id=3254 题意: 给你一片n*m的耕地,你可以在上面种玉米.但是其中有一些地方是荒芜的,不能种植.并且种植玉米的地方不能相邻.问你在这片地 ...

  2. Islands and Bridges(POJ2288+状压dp+Hamilton 回路)

    题目链接:http://poj.org/problem?id=2288 题目: 题意:求Hamilton 路径权值的最大值,且求出有多少条权值这么大的Hamilton路径. 思路:状压dp,dp[i] ...

  3. CH0103最短Hamilton路径 & poj2288 Islands and Brigdes【状压DP】

    虐狗宝典学习笔记: 取出整数\(n\)在二进制表示下的第\(k\)位                                                    \((n >> ...

  4. POJ 1185 炮兵阵地(状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

  5. POJ 3254 Corn Fields (状压dp)

    题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...

  6. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

  7. POJ 3254 - Corn Fields - [状压DP水题]

    题目链接:http://poj.org/problem?id=3254 Time Limit: 2000MS Memory Limit: 65536K Description Farmer John ...

  8. POJ 2411 Mondriaan's Dream ——状压DP 插头DP

    [题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...

  9. poj 2288 Islands and Bridges ——状压DP

    题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...

随机推荐

  1. IE支持直接查看Json数据注册表代码

    Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\MIME\Database\Content Type\application/json] ...

  2. JZOJ 3493. 【NOIP2013模拟联考13】三角形

    3493. [NOIP2013模拟联考13]三角形(triangle) (File IO): input:triangle.in output:triangle.out Time Limits: 10 ...

  3. BFS:HDU2597-Dating with girls(2) (分时间标记状态)

    Dating with girls(2) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  4. 笔记-python-lib-re

    笔记-python-lib-re 1.      re模块简介 re模块提供了与perl类似的正则匹配功能. 要搜索的模式和字符串都可以是Unicode字符串(str)以及8位字符串(bytes).但 ...

  5. Python 交互模式中 Delete/Backspace 键乱码问题

    进入 Python 交互模式,按下 Delete/Backspace 键,会出现 ^H 字符 解决方式: 1. 进到 Python 的Modules目录 [root@cyt-test Python-2 ...

  6. 配置Spring.NET

    先引入关键的程序集 Common.Logging.dll Spring.Core.dll 在配置文件配置中: <configSections> ...... <sectionGrou ...

  7. imageX

    imageX 编辑 ImageX 是一个命令行工具,原始设备制造商 (OEM) 和公司可以使用它来捕获.修改和应用基于文件的磁盘映像以进行快速部署.ImageX 可以使用 Windows 映像 (.w ...

  8. Ntdsutil.exe

    Ntdsutil.exe 编辑 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! Ntdsutil.exe 是一个为 Active Directory 提供管理设施的命令行工具 ...

  9. 69、Android 布局中轻松实现图片的全屏、居中、平铺

    public void paint() { if (item.laying_mode != 1)//平铺或者充满 { new AsyncTask<Void, Void, Void>() { ...

  10. ios开发学习笔记001-C语言基础知识

    先来学习一下C语言基础知识,总结如下: 在xcode下编写代码. 1.编写代码 2.编译:cc –c 文件名.c 编译成功会生成一个 .o的目标文件 3.链接:把目标文件.o和系统自带的库合并在一起, ...