题意:

  给一个无向图,n个点m条边,每个点有点权,要求找到一条哈密顿路径,使得该路径的f(path)值最大。输出f值,若有多条最大f值的路径,输出路径数量。

  f值由如下3点累加而来:

  (1)所有点权之和。

  (2)路径上相邻两点的点权之积。

  (3)路径上如果有连续的3个点是一个三角形(即3点成环),则累加三点的点权之积。

思路:

  根据f值的计算方式,第一项基本是不会变的,其他两项与路径有关。由于需要计算第3点,所以状态还需要记录每个状态的最后两个点(有序的),来判断是否为三角形。那么状态表示为[哪些点浏览过][倒数第2个点][末节点],如果是在刚开始,只有1个点,那么第二维就是0就行了。路径数是根据DP的过程来计算的,开一个和状态数一样的数组保存即可。

  注意点:路径统计要小心,图可能不连通,可能只有1个点,路径数可能爆LL?

 //#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <deque>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
int n, w[N];
LL cnt[<<][N][N], dp[<<][N][N],ans, ans2;
bool g[N][N]; void fuck(int s,int i,int k)
{
for(int j=; j<=n; j++) //枚举终点
{
if( (s&(<<j-)) || !g[i][j] ) continue;//已经走过or无路径 LL c=cnt[s][k][i];
LL v=dp[s][k][i]+w[i]*w[j];
if( g[k][j] ) v+=w[k]*w[i]*w[j]; //三角形出现 LL &cc=cnt[s|(<<j-)][i][j];
LL &dd=dp[s|(<<j-)][i][j];
if( dd<=v )
{
if(dd==v) cc+=c;
else cc=c;
dd=v;
}
}
}
void cal()
{
memset(dp,-,sizeof(dp));
memset(cnt,,sizeof(cnt));
ans=-;
ans2=-;
for(int i=; i<=n; i++)
{
dp[<<i-][][i]=;
cnt[<<i-][][i]=;
}
for(int s=; s<(<<n); s++)
{
for(int i=; i<=n; i++) //枚举k->i结尾
{
if( ( s&(<<i-) )== ) continue;
for(int k=; k<=n; k++)
{
if( k>&&(s&(<<k-))== || k==i ) continue;
if( dp[s][k][i]< ) continue;
fuck(s,i,k);
}
}
}
for(int i=; i<=n; i++) //枚举k->i结尾
{
for(int k=; k<=n; k++)
{
if(i==k || dp[(<<n)-][k][i]< ) continue;
if( ans==dp[(<<n)-][k][i] )
ans2+=cnt[(<<n)-][k][i];
else if( ans<dp[(<<n)-][k][i] )
{
ans=dp[(<<n)-][k][i];
ans2=cnt[(<<n)-][k][i];
}
}
}
} int main()
{
//freopen("input.txt","r",stdin);
int m, a, b, t, sum;cin>>t;
while(t--)
{
sum=;
scanf("%d%d",&n,&m);
memset(g,,sizeof(g));
for(int i=; i<=n; i++)
{
scanf("%d",&w[i]);
sum+=w[i];
}
for(int i=; i<m; i++)
{
scanf("%d%d",&a,&b);
g[a][b]=g[b][a]=true;
}
if(n==) printf("%d 1\n", w[]);
else
{
cal();
if(ans<) printf("0 0\n");
else printf("%lld %lld\n", ans+sum, ans2/);
}
}
return ;
}

AC代码

POJ 2288 Islands and Bridges (状压DP,变形)的更多相关文章

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

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

  2. poj 2288 Islands and Bridges——状压dp(哈密尔顿回路)

    题目:http://poj.org/problem?id=2288 不知为什么记忆化搜索就是WA得不得了! #include<iostream> #include<cstdio> ...

  3. [poj2288] Islands and Bridges (状压dp)

    Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we al ...

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

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

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

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

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

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

  7. 【POJ 2923】Relocation(状压DP+DP)

    题意是给你n个物品,每次两辆车运,容量分别是c1,c2,求最少运送次数.好像不是很好想,我看了网上的题解才做出来.先用状压DP计算i状态下,第一辆可以运送的重量,用该状态的重量总和-第一辆可以运送的, ...

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

    题目链接 题意 : 中文题不详述. 思路 :状压DP,1表示该位置放炮弹,0表示不放.dp[i][j][k],代表第 i 行的状态为k时第i-1行的状态为 j 时放置的最大炮弹数.只是注意判断的时候不 ...

  9. 动态规划晋级——POJ 3254 Corn Fields【状压DP】

    转载请注明出处:http://blog.csdn.net/a1dark 分析:刚开始学状压DP比较困难.多看看就发现其实也没有想象中那么难.这道题由于列数较小.所以将行压缩成二进制来看.首先处理第一行 ...

  10. POJ 1185 炮兵阵地 【状压DP】

    <题目链接> 题目大意: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...

随机推荐

  1. 文件解析库doctotext源码分析

    doctotext中没有make install选项,make后生成可执行文件 在buile目录下面有.so动态库和头文件,需要的可以从这里面拷贝 build/doctotext就是可执行程序.   ...

  2. ListView Item 里多种点击事件的用法

    思路:由于item里需要处理多种点击事件,所以不便于用listview的onItemClickListener,  需要在adapter里进行设置不同点击区域的onclicklistener 但是,有 ...

  3. 数据可视化系列--svg入门基础(一)

    一.前言 1.SVG(Scalable Vector Graphics)可伸缩矢量图形 特点: (1)使用xml格式来定义图形: (2)用来定义web上的使用的矢量图: (3)改变图像尺寸,图片质量不 ...

  4. Automake使用(高级)

    工程地址 automake语言国际化 最初工程目录结构 $ ls -l total 16 drwxrwxr-x. 2 fedora fedora 4096 May 10 10:38 build-aux ...

  5. How to use unity CreateExternalTexture on Android?

    http://stackoverflow.com/questions/33324753/how-to-use-unity-createexternaltexture-on-android Can so ...

  6. MySQL学习基础之一 — 数据库查询

    廖大神的练手神器:在线SQL: https://www.liaoxuefeng.com/wiki/1177760294764384/1179611432985088 运行MySQL等实际的数据库软件, ...

  7. appium运行遇到的坑01

    ..... File "build\bdist.win32\egg\appium\webdriver\errorhandler.py", line 29, in check_res ...

  8. git 基本操作——上传文件与项目分支管理

    创建并转入新分支:git checkout –b XX(其中XX代表分支名称) 将新分支发布在github上: git push origin Branch1 往分支中添加文件:git add mas ...

  9. katalon studio配置git与git项目创建

    katalon 是一款在2015年诞生的可以安装在windows.macOS.linux操作系统上,基于selenium 和 Appium 测试框架,并集成了这些框架的优点的自动化测试工具.关于这个工 ...

  10. Java基础笔记(二)——配置环境变量

    https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 到此处下载jdk,并安装.(选 ...