AtCoder Beginner Contest 352(补题)E

Problem Statement

You are given a weighted undirected graph 𝐺G with 𝑁N vertices, numbered 11 to 𝑁N. Initially, 𝐺G has no edges.

You will perform 𝑀M operations to add edges to 𝐺G. The 𝑖i-th operation (1≤𝑖≤𝑀)(1≤i≤M) is as follows:

  • You are given a subset of vertices 𝑆𝑖={𝐴𝑖,1,𝐴𝑖,2,...,𝐴𝑖,𝐾𝑖}Si={Ai,1,Ai,2,...,Ai,Ki} consisting of 𝐾𝑖Ki vertices. For every pair 𝑢,𝑣u,v such that 𝑢,𝑣∈𝑆𝑖u,v∈Si and 𝑢<𝑣u<v, add an edge between vertices 𝑢u and 𝑣v with weight 𝐶𝑖Ci.

After performing all 𝑀M operations, determine whether 𝐺G is connected. If it is, find the total weight of the edges in a minimum spanning tree of 𝐺G.

问题陈述

给你一个加权无向图 𝐺G ,其中有 𝑁N 个顶点,编号为 11 至 𝑁N 。最初, 𝐺G 没有边。

您需要执行 𝑀M 次操作来为 𝐺G 添加边。 𝑖i -th 操作 (1≤𝑖≤𝑀)(1≤i≤M) 如下所示:

  • 给你一个由 𝐾𝑖Ki 个顶点组成的顶点子集 𝑆𝑖={𝐴𝑖,1,𝐴𝑖,2,...,𝐴𝑖,𝐾𝑖}Si={Ai,1,Ai,2,...,Ai,Ki} 。对于每一对 𝑢,𝑣u,v ,即 𝑢,𝑣∈𝑆𝑖u,v∈Si 和 𝑢<𝑣u<v ,在顶点 𝑢u 和 𝑣v 之间添加一条边,权重为 𝐶𝑖Ci 。

执行所有 𝑀M 操作后,确定 𝐺G 是否相连。如果是,求 𝐺G 最小生成树中各条边的总重。

题意:

就是给定n个点,和m次操作 ,

每次操作给定 这个操作有 k个点 和 这k个点两两的边为 c

问构成的最小生成树。

思路:

我们可以先选着小的权重 间点进行连边。

可是这又m个操作,我们可以队这 m个操作进行排序;

对每次搞作,我们可以用并查集对 其操作中的每个点,进行求并查集求它的父节点。

当在这次搞作,存在有2个不同的父节点,这时,我们将这连个节点连起来,相当于这两个集合联通。

最小生成树满足全部的点都相连,且路径最小。

特判如果存在不止1个集合,返回-1。

代码:

复制代码
#include<bits/stdc++.h>
using namespace std;
class dsu
{
	public:
	vector<int> p;
	int n;
	dsu(int _n):n(_n)
	{
		p.resize(n);
		iota(p.begin(),p.end(),0);
	}
	inline int get(int x)
	{
		return (x == p[x])?x : (p[x] = get(p[x]));
	}
	
	inline bool unite(int x,int y)
	{
		x = get(x);
		y = get(y);
		if(x != y)
		{
			p[x] = y;
			return true;
		}
		return false;
	}
};
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n,m;
	cin >> n >>m;
	vector<int> c(m);
	vector<vector<int>> v(m);
	for(int i = 0;i < m;i++)
	{
		int foo;
		cin >> foo >> c[i];
		v[i].resize(foo);
		for(int j =0;j < foo;j++)
		{
			cin >> v[i][j];
			--v[i][j]; //为了重 0开始  0 ~ n-1这些点 
		}
	}
	
	vector<int> order(m);
	iota(order.begin(),order.end(),0); // 重 0 开始 的 一个递增 
	sort(order.begin(),order.end(),[&](int i,int j)
	{
		return c[i]<c[j];	 // 权值小的先整 
	});
	
//	for(int i = 0;i < m;i++)
//	{
//		cout <<order[i]<<endl;
//	}
	int comps = n;//找个集合多少个点  
	dsu d(n);
	int64_t ans = 0;
	for(int i : order)
	{
		set<int> s;
		for(int j : v[i])
		{
			s.insert(d.get(j)); // j的父节点 存入 
		}
		
		vector<int> u(s.begin(),s.end());
		
		for(int j = 1;j < int(u.size());j++) //遍历父节点的 只要将父节点连在一起就行 
		{
			assert(d.unite(u[j-1],u[j])); // 他们的父节点有关联 可以连在一起 
			comps -= 1;
			ans += c[i];
		}
		s
	}
	
	
	cout << (comps == 1 ? ans :-1) <<'\n';
	
	
	
	
	
	return 0;
}

时间复杂度:O(n*m*logn)

相关推荐
Wadli9 小时前
26.单调栈
算法
晨曦夜月9 小时前
进程的五大状态及特殊进程解析
linux·服务器·算法
吟安安安安9 小时前
适合短期冲刺的学习工作流(针对算法)
学习·算法
科研前沿9 小时前
什么是时空融合技术?
大数据·人工智能·数码相机·算法·重构·空间计算
weixin_4217252610 小时前
C语言常用字符串函数:长度、比较、拼接和查找
c语言·字符串函数·查找·比较·长度
AI科技星10 小时前
全域数学本源公理:0、1、∞ 三者核心关系 (典籍定稿版)
人工智能·算法·数学建模·数据挖掘·量子计算
AI科技星10 小时前
全域数学·第卷:场计算机卷(场空间计算机)【乖乖数学】
java·开发语言·人工智能·算法·机器学习·数学建模·数据挖掘
Deepoch10 小时前
数学模型驱动:Deepoc 低幻觉数学大模型助力发动机全周期智能优化
人工智能·算法·机器学习·deepoc·数学大模型·低幻觉
嘻嘻哈哈樱桃10 小时前
牛客经典101题解题集--贪心算法+模拟
java·python·算法·贪心算法
AKDreamer_HeXY10 小时前
QOJ 12255 - 36 Puzzle 题解
数据结构·c++·数学·算法·icpc·qoj