#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=100100;
typedef long long ll;
int w[15];
int d[15][15];
int dp[1<<14][15][15];
ll num[1<<14][15][15];
int n,m;
int main(){
// freopen("F:\\123.txt","r",stdin);
int q,u,v;
scanf("%d",&q);
while(q--){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&w[i]);
}
memset(d,-1,sizeof(d));
memset(dp,-1,sizeof(dp));
memset(num,0,sizeof(num));
for(int i=0;i<m;i++){
scanf("%d%d",&u,&v);
u--;v--;
d[u][v]=d[v][u]=1;
dp[1<<v |1<<u][v][u]=dp[1<<u | 1<<v][u][v]= w[v]*w[u];
num[1<<v | 1<<u][v][u]=num[1<<u |1<<v][u][v]=1;
}
if(n==1){
printf("%d 1\n",w[0]);
continue;
}
for(int i=0;i<=((1<<n)-1);i++){
for(int j=0;j<n;j++){
if(((1<<j)&i) ==0) continue;
for(int k=0;k<n;k++){
if(((1<<k)&i )==0 ) continue;
if(d[j][k]==-1 ) continue;
if(dp[i][j][k]==-1) continue;
for(int u=0;u<n;u++) {
if((1<<u)&i) continue;
if(d[k][u]==-1) continue;
if(j==u) continue;
int tmp=dp[i][j][k]+ w[k]*w[u] ;
if(d[j][u]==1){
tmp+= w[j]*w[k]*w[u];
}
if(dp[i|(1<<u)][k][u] <tmp )
{
dp[i | (1<<u)][k][u]= tmp;
num[i|(1<<u)][k][u]= num[i][j][k];
} else if(dp[i|(1<<u)][k][u]==tmp ) {
num[i|(1<<u)][k][u]+= num[i][j][k];
}
}
}
}
}
int ans1 =0;
long long ans2 =0 ;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(d[i][j]==1){
// printf("dp[%d][%d][%d]=%d num[%d][%d][%d]=%I64d\n",(1<<n)-1,i,j,dp[(1<<n)-1][i][j],
// (1<<n)-1,i,j,num[(1<<n)-1][i][j]);
if(ans1<dp[(1<<n)-1][i][j]){
// printf("ans1 %d dp[%d][%d][%d]=%d \n",ans1,(1<<n)-1,i,j,dp[(1<<n)-1][i][j]);
ans1=dp[(1<<n)-1][i][j];
ans2=num[(1<<n)-1][i][j];
}else if(ans1==dp[(1<<n)-1][i][j]){
// printf("else ans1 %d dp[%d][%d][%d]=%d \n",ans1,(1<<n)-1,i,j,dp[(1<<n)-1][i][j]);
ans2+= num[(1<<n)-1][i][j];
}
}
}
}
if(ans1!=0)
for(int i=0;i<n;i++){
ans1+=w[i];
}
// printf("%d %I64d\n",ans1,ans2/2ll);
cout<<ans1<<" "<<ans2/2<<endl;
}
return 0;
}
poj 2288Islands and Bridges
最新推荐文章于 2018-07-17 16:29:38 发布