UVA 1151 Buy or build(并查集之六)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 1151 Buy or build(并查集之六)相关的知识,希望对你有一定的参考价值。
题意:n个结点,以及m个组合,可以任意选择。求最小花费。
因为组合最多只有8个,可以枚举。
#include<stdio.h> #include<math.h> #include<algorithm> #include<string.h> #define MAX 1007 #define INTMAX (int)1e9 using namespace std; struct list_buy { int num; int price; int node[MAX]; }; struct list_buy l[10]; struct point { int x; int y; }; struct point p[MAX]; struct Line { int u; int v; int w; }; struct Line line[MAX*MAX]; int n,m,x[10],flag[MAX],count_line,min_ans; int pre[MAX]; int cmp(struct Line a,struct Line b) { return a.w<b.w; } int cal(struct point a,struct point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } void init() { for(int i=0;i<n;i++) { pre[i]=i; flag[i]=0; } } int find(int x) { int r=x; while(r!=pre[r]) r=pre[r]; int i=x,j; while(i!=r) { j=pre[i]; pre[i]=r; i=j; } return r; } void join(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) pre[fx]=fy; } int kruskal() { int ans=0; sort(line,line+count_line,cmp); for(int i=0;i<count_line;i++) { int fx=find(line[i].u); int fy=find(line[i].v); if(fx!=fy) { ans+=line[i].w; pre[fx]=fy; for(int j=0;j<n;j++) pre[j]=find(j); int temp=0; for(int j=0;j<n-1;j++) { if(pre[j]!=pre[j+1]) { temp=1; break; } } if(temp==0) return ans; } } return ans; } int solve() { int ans=0; init(); for(int i=0;i<m;i++) { if(x[i]) { ans+=l[i].price; for(int j=0;j<l[i].num-1;j++) { int fx=find(l[i].node[j]); int fy=find(l[i].node[j+1]); pre[fx]=fy; } } } int temp=0; for(int i=0;i<n-1;i++) { if(pre[i]!=pre[i+1]) { temp=1; break; } } if(temp==0) return ans; else { temp=kruskal(); if(temp!=-1) ans+=temp; else return -1; } return ans; } void fun(int t) { if(t>=m) { int ans=solve(); if(ans<min_ans&&ans!=-1) min_ans=ans; } else { for(int i=0;i<=1;i++) { x[t]=i; fun(t+1); } } } int main() { int T; //freopen("in.cpp","r",stdin); while(scanf("%d",&T)!=EOF) { while(T--) { count_line=0; min_ans=INTMAX; scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d",&l[i].num,&l[i].price); for(int j=0;j<l[i].num;j++) { scanf("%d",&l[i].node[j]); l[i].node[j]--; } } for(int i=0;i<n;i++) { scanf("%d%d",&p[i].x,&p[i].y); } for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { if(i==j) continue; line[count_line].u=i; line[count_line].v=j; line[count_line].w=cal(p[i],p[j]); count_line++; } } fun(0); printf("%d\n",min_ans); if(T!=0) printf("\n"); } } return 0; }
以上是关于UVA 1151 Buy or build(并查集之六)的主要内容,如果未能解决你的问题,请参考以下文章
UVa 1151 - Buy or Build(最小生成树)
UVa1151 Buy or Build (最小生成树,枚举子集)
uva 1151Buy or Build(图论 最小生成树)