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 CiCi+1 in the path, we add the product Vi*Vi+1. And for the third part, whenever three consecutive islands CiCi+1Ci+2 in the path forms a triangle in the map, i.e. there is a bridge between Ci and Ci+2, we add the product Vi*Vi+1*Vi+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.
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
哈密顿回路
该词条缺少词条分类,补充相关内容帮助词条更加完善!立刻编辑>>
哈密顿路径问题在上世纪七十年代初,终于被证明是“NP完备”的。据说具有这样性质的问题,难于找到一个有效的算法。实际上对于某些顶点数不到100的网络,利用现有最好的算法和计算机也需要比较荒唐的时间(比如几百年)才能确定其是否存在一条这样的路径。
从图中的任意一点出发,路途中经过图中每一个结点当且仅当一次,则成为哈密顿回路。
要满足两个条件:
1.封闭的环
2.是一个连通图,且图中任意两点可达
经过图(有向图或无向图)中所有顶点一次且仅一次的通路称为哈密顿通路。
经过图中所有顶点一次且仅一次的回路称为哈密顿回路。
具有哈密顿回路的图称为哈密顿图,具有哈密顿通路但不具有哈密顿回路的图称为半哈密顿图。
平凡图是哈密顿图。
题意:求一条哈密顿回路,但是权值计算不同,包括三部分:1经过个所有点的权值相加。2经过的连续两个点的权值的乘积。3,能够构成三角型的连续三个点的乘积。这些全部加起来就是这条回路的总权值。输出最大权值和这个最大权值的路线有多少条。
这题很难构造DP方程,因为题目中要加上构成三角形的乘积,所以用三维dp[state][i][j],state是当前状态,i,j是相邻的两条边,用这两条边去更新新的状态因为三维可以在更新时就判断是否满足三角形减少了下个状态时的判断,,
虽然模板是TSP但是还是很复杂的,数据量开long long
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 14;
typedef long long LL;
LL dp[1<<N][N][N], road[1<<N][N][N], v[N], s[N][N];
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, m;
scanf("%d %d", &n, &m);
memset(dp,-1,sizeof(dp));
memset(road,0,sizeof(road));
memset(s,0,sizeof(s));
for(int i=1;i<=n;i++)
scanf("%d", &v[i]);
for(int i=0;i<m;i++)
{
LL x, y;
scanf("%lld %lld", &x, &y);
s[x][y]=s[y][x]=1;
}
if(n==1)
{
printf("%lld 1\n",v[1]);
continue;
}
int num=(1<<n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=j&&s[i][j])
{
int state=1<<(i-1);
state|=(1<<(j-1));
dp[state][i][j]=v[i]+v[j]+v[i]*v[j];
road[state][i][j]=1;
}
}
}
for(int now=0;now<num;now++)
{
for(int i=1;i<=n;i++)
{
if(!(now&(1<<(i-1))))
continue;
for(int j=1;j<=n;j++)
{
if(!(now&(1<<(j-1)))||s[i][j]==0||i==j)
continue;
if(dp[now][i][j]==-1)
continue;
for(int k=1;k<=n;k++)
{
if(now&(1<<(k-1)))
continue;
if(s[j][k]==0||i==k||j==k)
continue;
int sum=dp[now][i][j]+v[k]+v[j]*v[k];
if(s[i][k])
sum+=(v[i]*v[j]*v[k]);
int state=now|(1<<(k-1));
if(dp[state][j][k]<sum)
{
dp[state][j][k]=sum;
road[state][j][k]=road[now][i][j];
}
else if(dp[state][j][k]==sum)
{
road[state][j][k]+=road[now][i][j];
}
}
}
}
}
LL ans=0, cnt=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j||s[i][j]==0||dp[num-1][i][j]==-1)
continue;
else if(dp[num-1][i][j]>ans)
{
ans=dp[num-1][i][j];
cnt=road[num-1][i][j];
}
else if(dp[num-1][i][j]==ans)
{
cnt+=road[num-1][i][j];
}
}
}
printf("%lld %lld\n",ans,cnt/2);
}
return 0;
}