//http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87121#problem/C
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int M = 1000 * 999/2+5; int w[100],nq[100]; int qs[100][100]; int pre[3013]; int eds ,n; struct c_xy{ int x,y; }point[3100]; struct node{ int u,v; int cost; }edges[M]; bool cmp(node a,node b){ return a.cost < b.cost; } void init(){ int k = 0; for(int i = 0;i<n;i++) for(int j = i+1;j<n;j++){ edges[k].cost = (point[i].x - point[j].x) * (point[i].x - point[j].x) + (point[i].y - point[j].y)*(point[i].y - point[j].y); edges[k].u = i+1; edges[k].v = j+1; k++; } eds = k; } void init_union(){ for(int i = 0;i <= 3010;i++){ pre[i] = i; } } int find(int x) { int k, j, r; r = x; while(r != pre[r]) r = pre[r]; k = x; while(k != r) { j = pre[k]; pre[k] = r; k = j; } return r; } int main(){ int flag = 1; int q; int t; scanf("%d",&t); while(t--){ long long ans = 0x3f3f3f3f; scanf("%d%d",&n,&q); for(int i = 0;i<q;i++){ scanf("%d%d",&nq[i],&w[i]); for(int j = 0;j<nq[i];j++) scanf("%d",&qs[i][j]); } for(int i = 0;i<n;i++){ scanf("%d%d",&point[i].x,&point[i].y); } init(); sort(edges,edges+eds,cmp); for(int i = 0;i<(1<<q);i++){ init_union();//并查集的初始化 long long s = 0; int nums = 0; for(int j = 0;j<q;j++){ if(i&(1<<j)){ s+=w[j]; for(int k = 0;k<nq[j];k++){//如果选取这个集合,则进行并查集的处理,表示已经将这些链接了 int v_1 = find(qs[j][k]); int u_1 = find(qs[j][0]); if(u_1 != v_1){ nums++; pre[v_1] = u_1; } } } } for(int i = 0;i<eds&&nums < n-1;i++){ int u = find(edges[i].u); int v = find(edges[i].v); if(u!=v){ nums ++; pre[u] = v; s += edges[i].cost; } } ans = min(ans,s); } if(flag == 1){ flag = 0; }else puts(""); printf("%lld ",ans); } }