【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 }
View Code

 

像是没有区别= =

 

2016-11-01 22:24:10

posted @ 2016-11-01 22:19  konjak魔芋  阅读(239)  评论(0编辑  收藏  举报