Description

Given a map of islands and bridges that connect these islands, a Hamilton path, as we all know, is a path along the bridges such that it visits each island exactly once. On our map, there is also a positive integer value associated with each island. We call a Hamilton path the best triangular Hamilton path if it maximizes the value described below.

Suppose there are n islands. The value of a Hamilton path C1C2...Cn is calculated as the sum of three parts. Let Vi be the value for the island Ci. As the first part, we sum over all the Vi values for each island in the path. For the second part, for each edge CiC i+1 in the path, we add the product Vi*V i+1. And for the third part, whenever three consecutive islands CiC i+1i+2 in the path forms a triangle in the map, i.e. there is a bridge between Ci and C i+2, we add the product Vi*V i+1*V i+2.

Most likely but not necessarily, the best triangular Hamilton path you are going to find contains many triangles. It is quite possible that there might be more than one best triangular Hamilton paths; your second task is to find the number of such paths.

Input

The input file starts with a number q (q<=20) on the first line, which is the number of test cases. Each test case starts with a line with two integers n and m, which are the number of islands and the number of bridges in the map, respectively. The next line contains n positive integers, the i-th number being the Vi value of island i. Each value is no more than 100. The following m lines are in the form x y, which indicates there is a (two way) bridge between island x and island y. Islands are numbered from 1 to n. You may assume there will be no more than 13 islands. 

Output

For each test case, output a line with two numbers, separated by a space. The first number is the maximum value of a best triangular Hamilton path; the second number should be the number of different best triangular Hamilton paths. If the test case does not contain a Hamilton path, the output must be `0 0'.

Note: A path may be written down in the reversed order. We still think it is the same path.

Sample Input

2
3 3
2 2 2
1 2
2 3
3 1
4 6
1 2 3 4
1 2
1 3
1 4
2 3
2 4
3 4

Sample Output

22 3
69 1

Source

二进制表示点的到达状态。

状态压缩求哈密顿回路,基本思路如下:

F[i][j] (0<=i<2^n,0<=j<n) 表示所有点的访问状态为i并且目前处于点j时的最短路径。
在i的二进制表示下,第k(0<=k<n)位为1表示已经访问过点k。
F[0][0]=0,Others=+∞,求F[2^n-1][n-1]。
F[i][j]=Min{F[i^1<<k][k]+w(k,j) | 0<=k<n-1且(i>>k&1)=1}

在本题中由于要考虑“三角形”关系,故须开三维,f[到达状态][上一个到达的点][本次到达的点]=最优解

同时要统计方案数,由于方案可能很多,需要开LL

 /*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int f[<<][][];
long long num[<<][][];
int mp[][];
int v[];
int n,m;
int main(){
int Q;
scanf("%d",&Q);
while(Q--){
memset(f,-,sizeof(f));
memset(num,,sizeof(num));
memset(mp,,sizeof(mp));
scanf("%d%d",&n,&m);
int i,j,k,s;
for(i=;i<n;i++){
scanf("%d",&v[i]);
}
int x,y;
for(i=;i<=m;i++){
scanf("%d%d",&x,&y);
x--;y--;
mp[x][y]=mp[y][x]=;
}
if(n==){//单点特判
printf("%d 1\n",v[]);
continue;
}
for(i=;i<n;i++)//边界预处理
for(j=;j<n;j++)
if(i!=j && mp[i][j]){
f[(<<i)|(<<j)][i][j]=v[i]+v[j]+v[i]*v[j];
num[(<<i)|(<<j)][i][j]=;
}
for(i=;i<(<<n);i++)//连通状况
for(j=;j<n;j++)//枚举各岛
if((i&(<<j)))
for(k=;k<n;k++)
if(mp[j][k] && j!=k)
if((i&(<<k)) && f[i][j][k]!=-)//j和k枚举的岛都在i枚举范围内,且有上一个状态
for(s=;s<n;s++){
if(mp[k][s] && k!=s && !(i&(<<s)))
//k到s联通 s之前没走过
{
int val=f[i][j][k]+v[s]+v[k]*v[s];
if(mp[j][s])val+=v[j]*v[k]*v[s];//三角形特判
if(f[i|(<<s)][k][s]<val){//更新状态
f[i|(<<s)][k][s]=val;
num[i|(<<s)][k][s]=num[i][j][k];
}else if(f[i|(<<s)][k][s]==val)
num[i|(<<s)][k][s]+=num[i][j][k];
}
}
int ans=;
long long ansnum=;//数据很大!
for(j=;j<n;j++)
for(k=;k<n;k++){
if(k!=j && mp[j][k]){
s=(<<n)-;
if(ans<f[s][j][k]){
ans=f[s][j][k];
ansnum=num[s][j][k];
}
else if(ans==f[s][j][k])//解相同则累加方案数
ansnum+=num[s][j][k];
}
}
printf("%d %lld\n",ans,ansnum/);
}
return ;
}

POJ2288 Islands and Bridges的更多相关文章

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

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

  2. POJ2288 Islands and Bridges(TSP:状压DP)

    求一个图的哈密顿路径的最大权及其路径数.显然状态压缩+DP. dp[v][u][S] 表示从v走到当前顶点 u且走过的顶点集合是S的 最大权值和方案数 这题我用记忆化搜索,从终点开始递归进行,感觉这样 ...

  3. 【状压dp】Islands and Bridges

    Islands and Bridges Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11034   Accepted: 2 ...

  4. HDU 1668 Islands and Bridges

    Islands and Bridges Time Limit: 4000ms Memory Limit: 65536KB This problem will be judged on HDU. Ori ...

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

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

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

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

  7. DP:Islands and Bridges(POJ 2288)

    2015-09-21 造桥基建工程 题目大意,就是有n座岛和k座桥,要你找一条哈密顿圈(找完所有的岛,并且每个岛只经过一次),当经过一座岛就加上岛的价值,如果两岛联通,则加上两座岛的价值之积,如果三座 ...

  8. Islands and Bridges(POJ 2288状压dp)

    题意:给你一个图和每个点的价值,边权值为连接两点权值的积,走哈密顿通路,若到达的点和上上个点相连则价值加三点乘积,求哈密顿通路的最大价值,和最大价值哈密顿通路的条数. 分析:开始看这个题很吓人,但想想 ...

  9. poj 2288 Islands and Bridges

    题意: 给你一个双向连通图,求 获得权值最大 的 哈密顿通路的 权值 和 这个权值对应的数目: 其中权值计算方法是  列如 ABCD  权值是a+b+c+d+ab+bc+cd 如果 A,B,C  和B ...

随机推荐

  1. java 13-3 int类型的包装包Integer

    1.Integer的概述 需求1:把100这个数据的二进制,八进制,十六进制计算出来 需求2:判断一个数据是否是int范围内的.  首先你得知道int的范围是多大? 为了对基本数据类型进行更多的操作, ...

  2. smarty3缓存设置

  3. 【C#】WM 消息大全

    消息名 消息值 说明 WM_CREATE 0x0001 应用程序创建一个窗口 WM_DESTROY 0x0002 一个窗口被销毁 WM_MOVE 0x0003 移动一个窗口 WM_SIZE 0x000 ...

  4. 继续Wcf记录点滴

    之前说wcf以tcp协议作为通信方式的话会出现很多奇怪的bug,今天我把自己遇到的比较特殊的一个exception和解决方案列出来.主要是自己记录一下,顺便方便遇到这个问题的有缘人吧!废话不多说直接上 ...

  5. 华为访问列表traffic-policy案例

    1,最近某公司有个需求 2,配置为重点--在于思路 需求:192.168.1 3 5 8网段不能访问2.x网段 仅允许财务2.x访问1.253打印机. acl name permit_printer ...

  6. CentOS 7 安装桌面环境

    首先进入要使用root权限: 使用 yum grouplist可以看现在的安装情况以及支持哪些软件包. 使用 yum groupinstall "GNOME Desktop" &q ...

  7. CSS 动画之九-会呼吸的信封

    新年已经到来,各个网站都举办着各种不同类型的活动,'会呼吸的信封'有可能就是你遇到的其中一种.其实就是一个信封的样式,在封口处加上开合开合的动画效果,吸引用户去打开这个信封,点击后可能会送红包,优惠券 ...

  8. http 请求头设置缓存

     nginx不缓存设置 2013-08-15 10:47:39 分类: LINUX 在开发调试web的时候,经常会碰到因浏览器缓存(cache)而经常要去清空缓存或者强制刷新来测试的烦恼,提供下apa ...

  9. Android -- 创建数据库到SD卡

    SQLite 系统自带的SQLite是通过SQLiteOpenHelper实现的,而SQLiteOpenHelper是将数据库存储到/data/data/包名/databasas,这样做的话在没有ro ...

  10. LeetCode:Unique Binary Search Trees I II

    LeetCode:Unique Binary Search Trees Given n, how many structurally unique BST's (binary search trees ...