分析:
由此题的标签可以知道,我们需要用到并查集和01背包。
因为他要连起来卖,所以我们可以把他所有要连起来的卖的云的价格和价值累计到一朵云上,然后把被累计的云标记成不可用,然后再把可用的云用dp背包做出来,就可以算出最大的价值。
#include<stdio.h>
#define max(a,b) a>b?a:b
struct thing
{
int cost;
int value;
int parent;
}a[50000];
int dp[50100];
int find(int x)
{
if(a[x].parent==x) return x;
else {
a[x].parent=find(a[x].parent);
return a[x].parent;
}
}
void unionn(int x,int y)
{
int xx=find(x);
int yy=find(y);
a[xx].parent=yy;
//全部累计到根上
a[yy].cost+=a[xx].cost;
a[yy].value+=a[xx].value;
}
main()
{
int m,n,w;
scanf("%d%d%d",&m,&n,&w);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a[i].cost,&a[i].value);
a[i].parent=i;
}
for(int i=0;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
unionn(x,y);
}
// for(int i=1;i<=m;i++)
// {
// printf("i=%d cost=%d value=%d parent=%d\n",i,a[i].cost,a[i].value,a[i].parent);
// }
for(int i=1;i<=m;i++)
{
//若父节点不是自己,则就为被累计的云,跳过
if(a[i].parent!=i) continue;
for(int j=w;j>=a[i].cost;j--)
{
dp[j]=max(dp[j],dp[j-a[i].cost]+a[i].value);
}
}
printf("%d",dp[w]);
}