POJ2288 Islands and Bridges
Description
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+1C i+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
Output
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的更多相关文章
- [poj2288] Islands and Bridges (状压dp)
Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we al ...
- POJ2288 Islands and Bridges(TSP:状压DP)
求一个图的哈密顿路径的最大权及其路径数.显然状态压缩+DP. dp[v][u][S] 表示从v走到当前顶点 u且走过的顶点集合是S的 最大权值和方案数 这题我用记忆化搜索,从终点开始递归进行,感觉这样 ...
- 【状压dp】Islands and Bridges
Islands and Bridges Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 11034 Accepted: 2 ...
- HDU 1668 Islands and Bridges
Islands and Bridges Time Limit: 4000ms Memory Limit: 65536KB This problem will be judged on HDU. Ori ...
- 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 >> ...
- DP:Islands and Bridges(POJ 2288)
2015-09-21 造桥基建工程 题目大意,就是有n座岛和k座桥,要你找一条哈密顿圈(找完所有的岛,并且每个岛只经过一次),当经过一座岛就加上岛的价值,如果两岛联通,则加上两座岛的价值之积,如果三座 ...
- Islands and Bridges(POJ 2288状压dp)
题意:给你一个图和每个点的价值,边权值为连接两点权值的积,走哈密顿通路,若到达的点和上上个点相连则价值加三点乘积,求哈密顿通路的最大价值,和最大价值哈密顿通路的条数. 分析:开始看这个题很吓人,但想想 ...
- poj 2288 Islands and Bridges
题意: 给你一个双向连通图,求 获得权值最大 的 哈密顿通路的 权值 和 这个权值对应的数目: 其中权值计算方法是 列如 ABCD 权值是a+b+c+d+ab+bc+cd 如果 A,B,C 和B ...
随机推荐
- mysql数据库的备份和导入
mysqldump -u root -p --default-character-set = gbk -d demo_db>c:/appserv/www/demosql/sql1.sql//将数 ...
- jQuery的无new实例化
我只能说想法很好,设计的巧妙.看代码: var jQuery = function( selector, context ) { //执行了init函数并返回jQuery实例 return new j ...
- [原创]gerrit上分支操作记录(创建分支、删除分支)
Git分支对于一个项目的代码管理而言,是十分重要的! 许多久用git的朋友可能已经掌握的很牢固了,但对于一些初涉git的童鞋来说,可能还不是很熟悉. 在此,我将自己的一些操作经历做一梳理,希望能帮助到 ...
- 08Mybatis_入门程序——增加用户的操作以及返回自增主键的功能以及返回非自增主键的功能
本文要实现的功能是:给user表增加一个用户. 建表如下:
- 【转】【WPF】WPF样式(Style)—触发器
样式(Styles)由三部分构成:设置器(Setter).触发器(Triggers).资源(Resources). (1)触发器,让样式的使用更加准确.灵活和高效. (2)触发器(Triggers)主 ...
- 【转】【C#】【Thread】Mutex 互斥锁
Mutex:互斥(体) 又称同步基元. 当创建一个应用程序类时,将同时创建一个系统范围内的命名的Mutex对象.这个互斥元在整个操作系统中都是可见的.当已经存在一个同名的互斥元时,构造函数将会输出一个 ...
- linux vmstat 系统结果说明
可以用vmstat 显示系统负载等信息. 例如 vmstat 5 5,表示在T(5)秒时间内进行N(5)次采样. procs:r-->;在运行队列中等待的进程数b-->;在等待io的进程数 ...
- [转]redis 五种数据类型的使用场景
FROM : http://blog.csdn.net/gaogaoshan/article/details/41039581#t5 String 1.String 常用命令: 除了get.set.i ...
- C语言 生成随机数
#include<stdio.h> #include<time.h> #include<Windows.h> void main1(){ //定义一个时间类型 ti ...
- discuz编码转换UTF8与GBK互转完美适合Discuz3.x系列
由于一些网站通信编码的问题不得不把一直使用的网站编码由UTF8转为GBK,在转换过程中在官方看了很多方法,自己也都尝试了一些最后都没有能够成功,数据库的转换一直都是没有大问题,不存在丢失什么的,能看到 ...