题目连接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3592
二进制枚举
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<algorithm> 5 #define ll long long 6 using namespace std; 7 vector<int> mst; 8 const int maxn=1010; 9 int qsize[10],qcost[10],q[10][maxn]; 10 int x[maxn],y[maxn]; 11 int f[maxn]; 12 int cnt,ans; 13 14 struct edge 15 { 16 int u; 17 int v; 18 int w; 19 bool operator < (const edge &a ) 20 { 21 return w<a.w; 22 } 23 }e[maxn*maxn]; 24 25 int t,n,m; 26 void init() 27 { 28 for(int i=0;i<=n;i++) 29 f[i]=i; 30 ans=0; 31 cnt=0; 32 mst.clear(); 33 } 34 35 int gf(int x) 36 { 37 return x==f[x]?f[x]:f[x]=gf(f[x]); 38 } 39 40 void uni(int a,int b) 41 { 42 int pa=gf(a); 43 int pb=gf(b); 44 f[pa]=pb; 45 } 46 47 int gd(int i,int j) 48 { 49 int dx=x[i]-x[j]; 50 int dy=y[i]-y[j]; 51 return dx*dx+dy*dy; 52 } 53 54 void add(int u,int v,int w) 55 { 56 e[cnt].u=u; 57 e[cnt].v=v; 58 e[cnt].w=w; 59 cnt++; 60 } 61 62 63 void krustal() 64 { 65 int coun=0; 66 for(int i=0;i<cnt;i++) 67 { 68 if(gf(e[i].u)!=gf(e[i].v)) 69 { 70 uni(e[i].u,e[i].v); 71 ans+=e[i].w; 72 mst.push_back(i); 73 coun++; 74 if(coun==n-1) break; 75 } 76 } 77 } 78 79 void mincost () 80 { 81 82 for(int s=1;s<(1<<m);s++) //枚举 83 { 84 int temp=0; 85 for(int i=0;i<=n;i++) f[i]=i; 86 for(int i=0;i<m;i++) if(s&(1<<i)) 87 { 88 temp+=qcost[i]; 89 for(int j=0;j<qsize[i];j++) 90 for(int k=j+1;k<qsize[i];k++) 91 if(gf(q[i][j])!=gf(q[i][k])) uni(q[i][j],q[i][k]); 92 } 93 int len=mst.size(); 94 for(int i=0;i<len;i++) 95 { 96 int j=mst[i]; 97 if(gf(e[j].u)!=gf(e[j].v)) 98 { 99 temp+=e[j].w; 100 uni(e[j].u,e[j].v); 101 } 102 } 103 ans=min(ans,temp); 104 } 105 106 107 } 108 109 int main() 110 { 111 scanf("%d",&t); 112 while(t--) 113 { 114 scanf("%d%d",&n,&m); 115 init(); 116 for(int i=0;i<m;i++) 117 { 118 scanf("%d%d",&qsize[i],&qcost[i]); 119 for(int j=0;j<qsize[i];j++) 120 scanf("%d",&q[i][j]); 121 } 122 for(int i=1;i<=n;i++) 123 { 124 scanf("%d%d",&x[i],&y[i]); 125 } 126 for(int i=1;i<n;i++) 127 for(int j=i+1;j<=n;j++) 128 add(i,j,gd(i,j)); 129 sort(e,e+cnt); 130 krustal(); 131 mincost(); 132 printf("%d\n",ans); 133 if(t) printf("\n"); 134 } 135 136 }