dp[i][j][k] 表示状态为i (二进制第k位为1表示第(k+1)顶点在当前路径里),倒数第二个点为j,最后一个点为k的最大值
之后类似spfa求最常路一样求解,初始把所有单个顶点的状态加入队列里,n==1是特判。
/*
* =====================================================================================
*
* Filename: 2288.cpp
* Version: 1.0
* Created: 2013-08-28 21:53:35
* Revision: none
* Compiler: GNU C++
*
* Just like you,wait you forever~~
*
* =====================================================================================
*/
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define PB push_back
#define SIZE(x) (int)x.size()
#define clr(x,y) memset(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define reads(n) scanf ("%s", n)
#define ALL(t) (t).begin(),(t).end()
#define FOR(i,n,m) for (int i = n; i <= m; i ++)
#define ROF(i,n,m) for (int i = n; i >= m; i --)
#define IT iterator
#define FF first
#define SS second
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<string> vstring;
typedef pair<int, int> PII;
void RI (int& x){
x = 0;
char c = getchar ();
while (c == ' '||c == '\n') c = getchar ();
bool flag = 1;
if (c == '-'){
flag = 0;
c = getchar ();
}
while (c >= '0' && c <= '9'){
x = x * 10 + c - '0';
c = getchar ();
}
if (!flag) x = -x;
}
void RII (int& x, int& y){RI (x), RI (y);}
void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}
/**************************************END define***************************************/
const ll mod = 1e9+7;
const ll LINF = 1e18;
const int INF = 1e9;
const double EPS = 1e-8;
const int N = 14;
pair<ll, ll> dp[1<<(N-1)][N][N];
int w[N];
bool g[N][N], vis[1<<(N-1)][N][N];
void init (){
clr (dp, 0), clr (g, 0), clr (vis, 0);
}
int main (){
int T;
RI (T);
while (T --){
init ();
int n, m;
RII (n, m);
FOR (i, 1, n){
RI (w[i]);
}
while (m --){
int u, v;
RII (u, v);
g[u][v] = g[v][u] = 1;
}
queue<pair<PII, int> > q;
FOR (i, 1, n){
int val = (1<<(i-1));
dp[val][0][i].FF = w[i];
dp[val][0][i].SS = 1;
vis[val][0][i] = 1;
q.push (MP (MP (val, 0), i));
}
while (SIZE (q)){
pair<PII, int> t = q.front ();
q.pop ();
int x = t.FF.FF, y = t.FF.SS, z = t.SS;
vis[x][y][z] = 0;
FOR (i, 1, n){
if (g[z][i]&&(((1<<i-1)&x) == 0)){
ll val = dp[x][y][z].FF + w[i] + w[z] * w[i];
if (g[y][i]) val += w[y]*w[z]*w[i];
int tx = x|(1<<i-1), ty = z, tz = i;
if (val > dp[tx][ty][tz].FF){
dp[tx][ty][tz].FF = val;
dp[tx][ty][tz].SS = dp[x][y][z].SS;
if (!vis[tx][ty][tz]){
q.push (MP (MP (tx, ty), tz));
vis[tx][ty][tz] = 1;
}
}else if (val == dp[tx][ty][tz].FF){
dp[tx][ty][tz].SS += dp[x][y][z].SS;
if (!vis[tx][ty][tz]){
vis[tx][ty][tz] = 1;
q.push (MP (MP (tx, ty), tz));
}
}
}
}
}
int sta = (1<<n)-1;
ll maxx = 0, num = 0;
FOR (i, 0, n){
FOR (j, 1, n){
if (dp[sta][i][j].FF > maxx){
maxx = dp[sta][i][j].FF;
num = dp[sta][i][j].SS;
}else if (dp[sta][i][j].FF == maxx){
num += dp[sta][i][j].SS;
}
}
}
cout << maxx << " " << num/2 + num%2 << endl;
}
}