#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
int n, m;
int v[14];
int map[14][14];
int dp[8200][14][14];
LL cnt[8200][14][14];
int main() {
int i, j, k, x, cas;
scanf("%d", &cas);
while(cas--) {
scanf("%d%d", &n, &m);
int N = 1<<n;
for(i = 0; i < n; i++) scanf("%d", &v[i]);
memset(map, 0, sizeof(map));
while(m--) {
int x, y;
scanf("%d%d", &x, &y); x--; y--;
map[x][y] = map[y][x] = 1;
}
if(n == 1) {
printf("%d 1\n", v[0]);
continue;
}
memset(dp, -1, sizeof(dp));
memset(cnt, 0, sizeof(cnt));
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) if(i != j && map[i][j]) {
dp[(1<<i)|(1<<j)][i][j] = v[i]+v[j]+v[i]*v[j];
cnt[(1<<i)|(1<<j)][i][j] = 1;
}
for(i = 0; i < N; i++)
for(j = 0; j < n; j++) if(i&(1<<j))
for(k = 0; k < n; k++) if(i&(1<<k) && ~dp[i][j][k])
for(x = 0; x < n; x++) if(!(i&(1<<x)) && map[k][x]) {
int now = dp[i][j][k]+v[x]+v[x]*v[k];
if(map[j][x]) now += v[x]*v[k]*v[j];
int state = i|(1<<x);
if(dp[state][k][x] < now) {
dp[state][k][x] = now;
cnt[state][k][x] = cnt[i][j][k];
}
else if(dp[state][k][x] == now)
cnt[state][k][x] += cnt[i][j][k];
}
LL ans = 0;
int ma = 0;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) if(i != j)
ma = max(ma, dp[N-1][i][j]);
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) if(i != j)
if(ma == dp[N-1][i][j]) ans += cnt[N-1][i][j];
printf("%d %I64d\n", ma, ans>>1);
}
return 0;
}
POJ 2288 Islands and Bridges 状态压缩DP
最新推荐文章于 2021-05-08 12:28:08 发布