专栏文章

题解:UVA1151 买还是建 Buy or Build

UVA1151题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mioxr546
此快照首次捕获于
2025/12/03 02:52
3 个月前
此快照最后确认于
2025/12/03 02:52
3 个月前
查看原文
看到题目的 q8q\le8,非常小,可以直接先提前跑一遍最小生成树,跑完后再用 O(2q)O(2^q) 效率枚举购买的网络,最后取最小值输出即可(记得输出两个换行)。
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int T,n,q,f[N];//分别表示样例组数,节点个数,网络数,并查集用的父亲数组。 
int X[N],Y[N],w[N];//分别表示各个节点的横坐标,纵坐标,以及各个网络的价格。 
int in[10][N];//存储网络联通的各个节点编号 
struct node{
	int x,y,z;
	bool operator<(node A)const{
		return z<A.z;
	}
};
vector<node>edge;
inline int find(int x){
	return f[x]==x?x:f[x]=find(f[x]);
}
int main(){
	cin>>T;
	while (T--){
		edge.clear();
		cin>>n>>q;
		for (int i=1;i<=q;i++){
			cin>>in[i][0]>>w[i];
			for (int j=1;j<=in[i][0];j++)
				cin>>in[i][j];
		}
		for (int i=1;i<=n;i++){
			cin>>X[i]>>Y[i];
			for (int j=1;j<i;j++){
				edge.push_back({i,j,
				(X[i]-X[j])*(X[i]-X[j])+
				(Y[i]-Y[j])*(Y[i]-Y[j])});
			}
		}sort(edge.begin(),edge.end());
		int res=0,ans=0;
		for (int i=1;i<=n;i++)f[i]=i;
		for (int i=0;i<edge.size();i++){
			int x=edge[i].x,y=edge[i].y;
			x=find(x);y=find(y);
			if (x!=y){
				edge[res++]=edge[i];
				f[x]=y;
				ans+=edge[i].z;
			}
		}
		int s=(1<<q)-1;
		for (int i=1;i<=s;i++){
			int cnt=0;
			for (int j=1;j<=n;j++) f[j]=j;
			for (int j=1;j<=8;j++)
				if (i&(1<<j-1)){
					cnt+=w[j];
					for (int k=2;k<=in[j][0];k++){
						int x=in[j][k];
						int y=in[j][k-1];
						x=find(x);
						y=find(y);
						if (x!=y) f[x]=y;
					}
				}
			for (int j=0;j<n;j++){
				int x=edge[j].x,y=edge[j].y;
				x=find(x);y=find(y);
				if (x!=y){
					f[x]=y;
					cnt+=edge[j].z;
				}
			}
			ans=min(ans,cnt);
		}cout<<ans<<'\n';
		if (T) cout<<'\n';
	}
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...