P1195 口袋的天空

题目背景

小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。

有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。

题目描述

给你云朵的个数 �N,再给你 �M 个关系,表示哪些云朵可以连在一起。

现在小杉要把所有云朵连成 �K 个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。

输入格式

第一行有三个数 �,�,�N,M,K。

接下来 �M 行每行三个数 �,�,�X,Y,L,表示 �X 云和 �Y 云可以通过 �L 的代价连在一起。

输出格式

对每组数据输出一行,仅有一个整数,表示最小的代价。

如果怎么连都连不出 �K 个棉花糖,请输出 No Answer

输入输出样例

输入 #1复制

3 1 2
1 2 1

输出 #1复制

1

说明/提示

对于 30%30% 的数据,1≤�≤1001≤N≤100,1≤�≤1031≤M≤103;

对于 100%100% 的数据,1≤�≤1031≤N≤103,1≤�≤1041≤M≤104,1≤�≤101≤K≤10,1≤�,�≤�1≤X,Y≤N,0≤�<1040≤L<104。

1.该题用kruscal算法解决。

2.在一个图中要生成最小生成树,n个顶点需要n-1条边。根据题意要连成k个联通块,则需要n-k个边。

#include"stdio.h"
#include"stdlib.h"
struct node
{
	int u,v,w;
};
int f[200005]; 
struct node tree[200005];
int cmp(const void* p1,const void* p2)
{
	 struct node *a=(struct node *)p1;
	 struct node *b=(struct node *)p2;
	 if((*a).w>(*b).w) return 1;
	 return -1;
}
int find(int v)
{
	if(v==f[v]) return v;
	else return f[v]=find(f[v]);
}
void hb(int v,int u)
{
	int t1,t2;
	t1=find(v);
	t2=find(u);
	if(t1!=t2) f[t1]=t2;
}
main()
{
	int n,m,k;
	int i,j;
	scanf("%d %d %d",&n,&m,&k);
	for(i=1;i<=m;i++)
	scanf("%d %d %d",&tree[i].u,&tree[i].v,&tree[i].w);
	for(i=1;i<=n;i++) f[i]=i;
	qsort(tree,m+1,sizeof(tree[0]),cmp);
	//printf("\n\n");
	//for(i=1;i<=m;i++) printf("%d %d %d\n",tree[i].u,tree[i].v,tree[i].w);
	int count=0,sum=0;
	for(i=1;i<=m;i++)
	{
		if(find(tree[i].u)!=find(tree[i].v))
		{
			hb(tree[i].u,tree[i].v);
			count++;
			sum+=tree[i].w;
		}
		if(count>=n-k) break;
	}
	if(count<n-k) printf("No Answer");
	else printf("%d",sum);
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值