题解 洛谷P1455 【搭配购买】

\(\huge\mathbb{DESCRIPTION}\)
编号:洛谷\(1455\)
算法:并查集\(\texttt{Dp}\)背包
来源:无名小题
\(\huge\mathbb{SOLUTION}\)
这道题目我们可以用并查集来解决。
首先,我们要打几个函数:

  • \(\texttt{Init}\):每个点建一个家族
  • \(\texttt{Find}\):查询本家族代表元
  • \(\texttt{Merge}\):合并两个家族

接下来,我们考虑一下做一个\(01\)背包
我们先将每一个家族的价格和价值都放到一个点上。
然后在剩下的点上跑\(01\)背包的模板即可。
\(\huge\mathbb{CODE}\)

#include<bits/stdc++.h>
#define MAX 10001
using namespace std;
int TotalPoint,TotalEdge,Money;
int Weight[MAX],Value[MAX];
int Fa[MAX],Dp[MAX];
inline void Init();
inline int Find(int X);
inline void Merge(int X,int Y);
int main(void)
{
	register int i,j;
	cin>>TotalPoint>>TotalEdge;
	cin>>Money;
	Init();
	for(i=1;i<=TotalPoint;i++)
	{
		cin>>Weight[i]>>Value[i];
	}
	for(i=1;i<=TotalEdge;i++)
	{
		register int U,V;
		cin>>U>>V;
		Merge(U,V);
	}
	for(i=1;i<=TotalPoint;i++)
	{
		if(Fa[i]!=i)
		{
			Weight[Find(i)]+=Weight[i];
			Value[Find(i)]+=Value[i];
			Weight[i]=Value[i]=0;
		}
	}
	for(i=1;i<=TotalPoint;i++)
	{
		for(j=Money;j>=Weight[i];j--)
		{
			Dp[j]=max(Dp[j],Dp[j-Weight[i]]+Value[i]);
		}
	}
	cout<<Dp[Money]<<endl;
	return 0;
}
inline void Init()
{
	register int i;
	for(i=1;i<=TotalPoint;i++)
	{
		Fa[i]=i;
	}
}
inline int Find(int X)
{
	return X==Fa[X]?X:Fa[X]=Find(Fa[X]);
}
inline void Merge(int X,int Y)
{
	Fa[Find(X)]=Find(Y);
}
posted @ 2020-08-20 22:53  Bushuai_Tang  阅读(81)  评论(0编辑  收藏  举报