码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 1151 Buy or Build【最小生成树】

时间:2015-05-04 01:02:33      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:

题意:给出n个点的坐标,现在需要让这n个点连通,可以直接在点与点之间连边,花费为两点之间欧几里得距离的平方,也可以选购套餐,套餐中所含的点是相互连通的 问最少的花费

首先想kruskal算法中,被加入的边已经是最优的了,所以当选择完套餐后,之前被丢弃的边也不会再进入最小生成树

然后就可以先求一次原图的最小生成树,保存下进入最小生成树的n-1条边

再枚举选择的套餐的情况,再求最小生成树,这里用的二进制法枚举 最后维护一个最小值就可以了

 

 

思路虽然看懂了,可是代码根本就写不出来,看着标程写的,最后还是改了那么久-- sad----------

技术分享
  1 #include<iostream>  
  2 #include<cstdio>  
  3 #include<cstring> 
  4 #include <cmath> 
  5 #include<stack>
  6 #include<vector>
  7 #include<map> 
  8 #include<set>
  9 #include<queue> 
 10 #include<algorithm>  
 11 using namespace std;
 12 
 13 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
 14 
 15 typedef long long LL;
 16 const int INF = (1<<30)-1;
 17 const int mod=1000000007;
 18 const int maxn=1005;
 19 const int maxq=8;
 20 
 21 int n;
 22 int x[maxn],y[maxn],cost[maxn];
 23 vector<int> subn[maxn];
 24 
 25 int p[maxn];
 26 int find(int x) {return p[x]!=x? p[x]=find(p[x]):x;}
 27 
 28 struct edge{
 29     int u,v,d;
 30     edge(int u,int v,int d):u(u),v(v),d(d) {}
 31     bool operator <(const edge& rhs) const{
 32     return d<rhs.d;}
 33 };
 34 
 35 int mst(int cnt,const vector<edge>& e,vector<edge>& used){
 36     if(cnt==1) return 0;
 37     int m=e.size();
 38     int ans=0;
 39     used.clear();
 40     for(int i=0;i<m;i++){
 41         int u=find(e[i].u),v=find(e[i].v);
 42         int d=e[i].d;
 43         if(u!=v){
 44             p[u]=v;
 45             ans+=d;
 46             used.push_back(e[i]);
 47             if(--cnt==1) break;
 48         }
 49     }
 50     return ans;
 51 }
 52 
 53 int main(){
 54 //    freopen("in.txt","r",stdin);
 55 //    freopen("outttttttt.txt","w",stdout);
 56     int T,q;
 57     scanf("%d",&T);
 58     while(T--){
 59         scanf("%d%d",&n,&q);
 60         for(int i=0;i<q;i++){
 61             int cnt;
 62             scanf("%d %d",&cnt,&cost[i]);
 63             subn[i].clear();
 64             while(cnt--){
 65                 int u;
 66                 scanf("%d",&u);
 67                 subn[i].push_back(u-1);            
 68             }
 69         }
 70         
 71         for(int i=0;i<n;i++) scanf("%d %d",&x[i],&y[i]);
 72         
 73         vector<edge> e,need;
 74         
 75         for(int i=0;i<n;i++)
 76          for(int j=i+1;j<n;j++){
 77              int c=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
 78              e.push_back(edge(i,j,c));
 79          }
 80         
 81         for(int i=0;i<n;i++) p[i]=i;
 82         sort(e.begin(),e.end());
 83         
 84         int ans=mst(n,e,need);
 85         
 86         for(int mask=0;mask<(1<<q);mask++){
 87             
 88             for(int i=0;i<n;i++) p[i]=i;
 89             int cnt=n,c=0;
 90             
 91             for(int i=0;i<q;i++) if(mask & (1<<i)){
 92                 c+=cost[i];
 93                 for(int j=1;j<subn[i].size();j++){
 94                     int u=find(subn[i][j]),v=find(subn[i][0]);
 95                     if(u!=v){p[u]=v;cnt--;}
 96                 }
 97             }
 98             vector<edge> dummy;
 99             ans=min(ans,c+mst(cnt,need,dummy));
100         }
101         printf("%d\n",ans);
102         if(T) printf("\n");        
103     }
104     return 0;    
105 }
View Code

 

UVa 1151 Buy or Build【最小生成树】

标签:

原文地址:http://www.cnblogs.com/wuyuewoniu/p/4475078.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!