UVA 1151 Buy or Build (有某些特别的东东的最小生成树)
Posted konjak魔芋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 1151 Buy or Build (有某些特别的东东的最小生成树)相关的知识,希望对你有一定的参考价值。
【题意】
平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方。
另外还有q(0<=q<=8)个套餐,可以购买,如果你购买了第i个套餐,该套餐中的所有结点将变得相互连通,第i个套餐的花费为ci。
求最小花费。
Input
(1 ≤ n ≤ 1000) (0 ≤ q ≤ 8).The second integer is the the cost of the subnetwork
(not greater than 2 × 10^6). integer values (ranging from 0 to 3000)
Output...
Sample Input
1
7 3
2 4 1 2
3 3 3 6 7
3 9 2 4 5
0 2
4 0
2 0
4 2
1 3
0 5
4 4
Sample Output
17
【分析】
枚举套餐哦。其实生成树问题多一些东东的话都是枚举的吧?吗?
你一开始先排序好,枚举完就不用排序了。
LRJ说什么只考虑最小生成树上的边优化版本:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 #define Maxn 1010 9 #define INF 0xfffffff 10 11 int a[10][Maxn],c[10]; 12 int nx[Maxn],ny[Maxn]; 13 int n,q; 14 15 struct node 16 { 17 int x,y,c; 18 }t[Maxn*Maxn]; 19 int len,nl; 20 21 void ins(int x,int y,int c) 22 { 23 t[++len].x=x;t[len].y=y;t[len].c=c; 24 } 25 26 bool cmp(node x,node y) {return x.c<y.c;} 27 28 int mymin(int x,int y) {return x<y?x:y;} 29 int mymax(int x,int y) {return x>y?x:y;} 30 31 int fa[Maxn]; 32 int ffa(int x) 33 { 34 if(fa[x]!=x) fa[x]=ffa(fa[x]); 35 return fa[x]; 36 } 37 38 void ffind() 39 { 40 int ans=INF; 41 for(int i=0;i<(1<<q);i++) 42 { 43 int now=0; 44 for(int j=1;j<=n;j++) fa[j]=j; 45 int ft=-1; 46 for(int j=1;j<=q;j++) if((1<<j-1)&i) 47 { 48 for(int k=2;k<=a[j][0];k++) 49 fa[ffa(a[j][k])]=ffa(a[j][1]); 50 now+=c[j]; 51 } 52 int cnt=0; 53 for(int j=1;j<=n;j++) if(ffa(j)==j) cnt++; 54 for(int j=1;j<=nl;j++) 55 { 56 if(ffa(t[j].x)!=ffa(t[j].y)) 57 { 58 fa[ffa(t[j].x)]=ffa(t[j].y); 59 now+=t[j].c; 60 cnt--; 61 } 62 if(cnt==1) break; 63 } 64 ans=mymin(ans,now); 65 } 66 printf("%d\\n",ans); 67 } 68 69 int main() 70 { 71 int T; 72 scanf("%d",&T); 73 while(T--) 74 { 75 scanf("%d%d",&n,&q); 76 for(int i=1;i<=q;i++) 77 { 78 scanf("%d%d",&a[i][0],&c[i]); 79 for(int j=1;j<=a[i][0];j++) scanf("%d",&a[i][j]); 80 } 81 for(int i=1;i<=n;i++) 82 { 83 scanf("%d%d",&nx[i],&ny[i]); 84 } 85 len=0; 86 for(int i=1;i<=n;i++) 87 for(int j=i+1;j<=n;j++) 88 { 89 // double xx=(double)(nx[i]-nx[j]),yy=(double)(ny[i]-ny[j]); 90 int xx=nx[i]-nx[j],yy=ny[i]-ny[j]; 91 ins(i,j,xx*xx+yy*yy); 92 } 93 sort(t+1,t+1+len,cmp); 94 int cnt=0;nl=0; 95 for(int i=1;i<=n;i++) fa[i]=i; 96 for(int i=1;i<=len;i++) 97 { 98 if(ffa(t[i].x)!=ffa(t[i].y)) 99 { 100 fa[ffa(t[i].x)]=ffa(t[i].y); 101 cnt++; 102 t[++nl]=t[i]; 103 } 104 if(cnt==n-1) break; 105 } 106 ffind(); 107 if(T) printf("\\n"); 108 } 109 return 0; 110 }
其实我觉得不用也没什么??反正都排序选前面的,区别??
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 #define Maxn 1010 9 #define INF 0xfffffff 10 11 int a[10][Maxn],c[10]; 12 int nx[Maxn],ny[Maxn]; 13 int n,q; 14 15 struct node 16 { 17 int x,y,c; 18 }t[Maxn*Maxn]; 19 int len,nl; 20 21 void ins(int x,int y,int c) 22 { 23 t[++len].x=x;t[len].y=y;t[len].c=c; 24 } 25 26 bool cmp(node x,node y) {return x.c<y.c;} 27 28 int mymin(int x,int y) {return x<y?x:y;} 29 int mymax(int x,int y) {return x>y?x:y;} 30 31 int fa[Maxn]; 32 int ffa(int x) 33 { 34 if(fa[x]!=x) fa[x]=ffa(fa[x]); 35 return fa[x]; 36 } 37 38 void ffind() 39 { 40 int ans=INF; 41 for(int i=0;i<(1<<q);i++) 42 { 43 int now=0; 44 for(int j=1;j<=n;j++) fa[j]=j; 45 int ft=-1; 46 for(int j=1;j<=q;j++) if((1<<j-1)&i) 47 { 48 for(int k=2;k<=a[j][0];k++) 49 fa[ffa(a[j][k])]=ffa(a[j][1]); 50 now+=c[j]; 51 } 52 int cnt=0; 53 for(int j=1;j<=n;j++) if(ffa(j)==j) cnt++; 54 for(int j=1;j<=len;j++) 55 { 56 if(ffa(t[j].x)!=ffa(t[j].y)) 57 { 58 fa[ffa(t[j].x)]=ffa(t[j].y); 59 now+=t[j].c; 60 cnt--; 61 } 62 if(cnt==1) break; 63 } 64 ans=mymin(ans,now); 65 } 66 printf("%d\\n",ans); 67 } 68 69 int main() 70 { 71 int T; 72 scanf("%d",&T); 73 while(T--) 74 { 75 scanf("%d%d",&n,&q); 76 for(int i=1;i<=q;i++) 77 { 78 scanf("%d%d",&a[i][0],&c[i]); 79 for(int j=1;j<=a[i][0];j++) scanf("%d",&a[i][j]); 80 } 81 for(int i=1;i<=n;i++) 82 { 83 scanf("%d%d",&nx[i],&ny[i]); 84 } 85 len=0; 86 for(int i=1;i<=n;i++) 87 for(int j=i+1;j<=n;j++) 88 { 89 // double xx=(double)(nx[i]-nx[j]),yy=(double)(ny[i]-ny[j]); 90 int xx=nx[i]-nx[j],yy=ny[i]-ny[j]; 91 ins(i,j,xx*xx+yy*yy); 92 } 93 sort(t+1,t+1+len,cmp); 94 /*int cnt=0;nl=0; 95 for(int i=1;i<=n;i++) fa[i]=i; 96 for(int i=1;i<=len;i++) 97 { 98 if(ffa(t[i].x)!=ffa(t[i].y)) 99 { 100 fa[ffa(t[i].x)]=ffa(t[i].y); 101 cnt++; 102 t[++nl]=t[i]; 103 } 104 if(cnt==n-1) break; 105 }*/ 106 ffind(); 107 if(T) printf("\\n"); 108 } 109 return 0; 110 }
像是没有区别= =
2016-11-01 22:24:10
以上是关于UVA 1151 Buy or Build (有某些特别的东东的最小生成树)的主要内容,如果未能解决你的问题,请参考以下文章
UVa 1151 - Buy or Build(最小生成树)
UVa1151 Buy or Build (最小生成树,枚举子集)
uva 1151Buy or Build(图论 最小生成树)