状压dp,按排好序的数组依次填入dp
#include"iostream"
#include"cstdio"
#include"cstring"
#include"vector"
#include"algorithm"
using namespace std;
typedef long long LL;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
int n,m;
int vis[22];
int dig[1<<20];
LL dp[1<<20];
vector<int> G[22];
int cnt;
struct node{
int x,id;
}p[22];
bool cmp(node a, node b)
{
return a.x > b.x;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
while(~scanf("%d%d",&n,&m)) {
for(int i = 1; i <= n; i++) {
scanf("%d",&p[i].x);
p[i].id = i;
G[i].clear();
}
sort(p+1,p+1+n,cmp);
for(int i = 1; i <= n; i++) vis[p[i].id] = i;
for(int i = 1; i < (1<<n); i++) dig[i] = __builtin_popcount(i);
for(int i = 1,u,v; i <= m; i++) {
scanf("%d%d",&u,&v);
if(u == v) continue;
G[vis[u]].push_back(vis[v]);
G[vis[v]].push_back(vis[u]);
}
dp[0] = 0;
for(int i = 1; i < (1<<n); i++) {
dp[i] = INFLL;
for(int j = 1; j <= n; j++) if(i&(1<<(j-1)) ) {
int l = i^(1<<(j-1));
int cnt = 0;
for(int k = 0; k < G[j].size(); k++){
if(i&(1<<(G[j][k]-1)) ) cnt++;
}
int sz = G[j].size();
dp[i] = min(dp[i],dp[l] + 1LL*p[dig[i]].x*(sz-2*cnt));
}
}
printf("%lld\n",dp[(1<<n)-1]);
}
return 0;
}