题解 洛谷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);
}
不要妄图追上西坠的太阳,而是要在黎明前就等着它!