【2020.10.24 洛谷 SSL团队赛 普及组】T3 U136293 国王饮水记

102 篇文章 1 订阅
67 篇文章 0 订阅

题目描述
BFrGjg.jpg


输入格式
BFrNHs.jpg

输出格式
BFrdNq.jpg


输入输出样例

输入 #1

5 10
5 2 18903
1 2 74504
5 1 22377
1 4 55995
3 1 44838
4 1 19622
1 2 62132
1 5 59540
5 4 56342
5 3 27255

输出 #1

18903 1
93407 3
41280 3
97275 4
142113 5
105740 5
105740 5
105740 5
105740 5
88157 5


说明/提示

数据规模与约定
BFrD3T.jpg

提示
BFrrgU.jpg


解题思路
由于边数⽐较少,每次采取 Kruskal 算法,这个算法是可以求出最⼤的最⼩⽣成森林的。连
通块⼤⼩可以在并查集⾥顺便维护。
第⼆问的答案⼀定是唯⼀的,否则可以通过加⼀条边连通两个不同答案情况的连通块,也就是说这两个答案均不是最⼤的最⼩⽣成森林。

PS:注意到,读⼊⼀条新边时,之前的边集已经按照⻓度排好序,可以直接寻找到相应的位置插⼊,省去了每次排序的复杂度。


代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int n,m,ans,cnt,fa[6000],s[6000];
struct c{
	int x,y,w;
}a[6000]; 
int find(int a)
{
	if(fa[a]==a) return a;
	else return fa[a]=find(fa[a]);
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
		for(int j=i;j>0&&a[j].w<a[j-1].w;j--)
			swap(a[j],a[j-1]);
		int ans=0,cnt=0;
		for(int j=1;j<=n;j++)
		{
			fa[j]=j;
			s[j]=1;
		}
		for(int j=1;j<=i&&cnt<=n-1;j++)
		{
			int x=find(a[j].x);
			int y=find(a[j].y);
			if(x!=y)
			{
				ans+=a[j].w;
				fa[x]=fa[y];
				s[y]+=s[x];
				++cnt;
			}
		}
		printf("%d %d\n",ans,s[find(1)]); 
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值