【cdoj 1338】郭大侠与英雄学院 并查集和矩阵那点事

ok,这道题我就写详细一点吧,毕竟剩下那几道题我都不想再写了,而且再好好消化一下子。

首先思考矩阵中没有重复元素的情况,这样的话就很简单了,只用把所有的元素输入进去再然后排序从小到大直接输出,在每一次输出的时候判断所在元素的这一行和列的最大编号(新的编号),然后将行和列中最大编号加一得到答案,有点类似于贪心的写法。然而,然而,让人郁闷的是会出现重复,那如果直接开一个vis数组储存当前点的最大不就行了吗?当然没有那么简单,因为在本题中,只有同行或者同列才会有影响,而如果不是同行或者同列,即使再相同,也不干人家什么屁事对吧。

既然需要把同行同列的元素一起考虑(他们需要一个相同的新编号),所以很容易想到把行和列相同的元素看成一个集合,而题目中会出现很多不同的集合,自然而然的想到并查集(然而我并没有想到怎么实现)。把同行同列相同的元素打包他们拥有相同的编号


再来说说实现吧,毕竟想对写不对是一件很恶心的是

先把所有元素从小到大排序,保证每一次把相同元素处理完,然后分段处理(每一段元素相同)

再用4次循环

第一次 :从相同元素的头到尾,找出在哪些行和列中元素出现过,并用数组把行和列出现过的元素记录(下一步有用)

2:因为是一个集合,把同行同列的打包加进来

3:找到一个集合的最小应该是多少,用根节点记录下来(因为是并查集) x=max

#include
#include
#include
#include
using namespace std;
int n,m;

struct node{
	int x,y,v;
	bool operator <(const node& b)const{
		return v

( x , max ( hx[j] , hy[j] ) )

4.更新每行每列的最大值

你可能感兴趣的:(ac之路,数据结构)