题解 洛谷P1525 【关押罪犯】

\(\huge\mathbb{DESCRIPTION}\)
编号:洛谷\(1525\)
算法:并查集贪心
来源:\(NOIP\ TG\ 2010\ T3\)
\(\huge\mathbb{SOLUTION}\)
这道题目我们可以用并查集来解决。
首先,我们要打几个函数:

  • \(\texttt{Find}\):查询本家族代表元
  • \(\texttt{Merge}\):合并两个家族
  • \(\texttt{Check}\):看两个元素是否在同一个家族中

然后,我们要考虑一个贪心
首先,我们把这些矛盾按照值排序。
我们要尽量把矛盾值大的错开。
然后,就豁然开朗啦~
具体细节也可以看代码~
\(\huge\mathbb{CODE}\)

#include<bits/stdc++.h>
#define MAX 20001
using namespace std;
struct Struct
{
	int PeoA;
	int PeoB;
	int How;
	inline bool operator < (const Struct &X)const
	{
		return How>X.How;
	}
};
int People,Thing;
Struct Criminal[5*MAX];
int Fa[MAX];
int Prison[MAX];
inline int Find(int X);
inline void Merge(int X,int Y);
inline bool Check(int X,int Y);
int main(void)
{
	register int i;
	cin>>People>>Thing;
	for(i=1;i<=People;i++)
	{
		Fa[i]=i;
	}
	for(i=1;i<=Thing;i++)
	{
		cin>>Criminal[i].PeoA>>Criminal[i].PeoB>>Criminal[i].How;
	}
	sort(Criminal+1,Criminal+Thing+1);
	for(i=1;i<=Thing+1;i++)
	{
		if(Check(Criminal[i].PeoA,Criminal[i].PeoB))
		{
			cout<<Criminal[i].How<<endl;
			break;
		}
		else
		{
			if(!Prison[Criminal[i].PeoA])
			{
				Prison[Criminal[i].PeoA]=Criminal[i].PeoB;
			}
			else
			{
				Merge(Prison[Criminal[i].PeoA],Criminal[i].PeoB);
			}
			if(!Prison[Criminal[i].PeoB])
			{
				Prison[Criminal[i].PeoB]=Criminal[i].PeoA;
			}
			else
			{
				Merge(Prison[Criminal[i].PeoB],Criminal[i].PeoA );
			}
		}
	}
	return 0;
}
inline int Find(int X)
{
	return X==Fa[X]?X:Fa[X]=Find(Fa[X]);
}
inline void Merge(int X,int Y)
{
	register int Fx,Fy;
	Fx=Find(X),Fy=Find(Y);
	Fa[Fx]=Fy;
}
inline bool Check(int X,int Y)
{
	if(Find(X)==Find(Y))
	{
		return true;
	}
	return false;
}
posted @ 2020-08-19 15:43  Bushuai_Tang  阅读(111)  评论(0编辑  收藏  举报