ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vijos1234 口袋的天空 题解

2020-04-05 14:43:30  阅读:306  来源: 互联网

标签:口袋 连通 ch prim Vijos1234 题解 int while kkk


博客园同步

原题链接

简要题意:

求把一个图分成 kkk 个连通块并连接连通块的最小价值。

一种类似于 prim\texttt{prim}prim 贪心的做法。

即用 并查集 维护当前节点所属连通块。

然后按边权从小到大排序选择,只要两个节点 连通块不同,就 将它们变成同一个连通块

用一个变量记录选过的 权值和边数 。最终看能不能选到 kkk 个即可。

时间复杂度:O(n+m)O(n+m)O(n+m).(并查集有个 α\alphaα 的常数,但因为 4\leq 4≤4 被忽略,特此说明

实际得分:100pts100pts100pts.

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

const int N=1e4+1;

inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}

struct data {
	int u,v,w;
}G[N];
int n,m,k,f[N];

inline bool cmp(data x,data y) {
	return x.w<y.w;
}

inline int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}

int main(){
	n=read(),m=read(),k=read();
	for(int i=1;i<=m;i++) G[i].u=read(),G[i].v=read(),G[i].w=read();
	if(m<n-k) {puts("No Answer");return 0;}
	for(int i=1;i<=n;i++) f[i]=i;
	sort(G+1,G+1+m,cmp); int x=n-k,ans=0;
	for(int i=1;i<=m;i++)
		if(find(G[i].u)-find(G[i].v)) {
			x--; ans+=G[i].w;
			f[find(G[i].u)]=find(G[i].v);
			if(!x) break;
		}
	if(!x) printf("%d\n",ans);
	else puts("No Answer");	
	return 0;
}

标签:口袋,连通,ch,prim,Vijos1234,题解,int,while,kkk
来源: https://blog.csdn.net/bifanwen/article/details/105300522

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有