$\huge \color{orange}{成魔之路->}$ $\huge \color{purple}{算法提高课题解}$
思路:
1. 将组合搭配的云朵看成是一个整体物品
2. 用并查集将搭配的云朵合并集合,并维护 v[i] 和 w[i]
3. 对组合搭配的云朵做一遍 01 背包,即只有是根节点时才 dp
完整代码
#include<bits/stdc++.h>
using namespace std;
const int N = 10010;
int n,m,vol;
int v[N],w[N];
int p[N];
int f[N];
int find(int x)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int main()
{
cin>>n>>m>>vol;
for(int i=1;i<=n;i++)
{
cin>>v[i]>>w[i];
p[i]=i;
}
while(m--)
{
int a,b;
cin>>a>>b;
//找到根节点
int pa=find(a),pb=find(b);
if(pa!=pb)
{
//合并体积
v[pb]+=v[pa];
//合并价值
w[pb]+=w[pa];
//合并集合,必须是最后一步
p[pa]=pb;
}
}
// 01背包问题
for(int i=1;i<=n;i++)
if(p[i]==i)
for(int j=vol;j>=v[i];j--)
f[j]=max(f[j],f[j-v[i]]+w[i]);
cout<<f[vol]<<endl;
return 0;
}
为什么必须是最后一步???
只要在括号内,爱第几步第几步,你就算不是在括号内部,你把它放在if(pa!=pb)之前 int pa=find(a),pb=find(b);之后,也可以过不信可以自己复制代码试一试,都可以AC,看了几个都这么说的,难道就没人质疑吗?还是就像y总说的:天下题解一大抄吗?????
确实是这个样子。
感谢您的质疑精神,我看了一会没造出数据。
可能是因为
这一个语句没有改变$pa$,$pb$的值。