洛谷P1455 搭配购买(并查集)

【题目信息】

洛谷P1455 搭配购买、

 

【审题】

云和云之间有依赖关系,买一朵就要买与它相关的所有朵。

 

【分析】

1.使用并查集,路径压缩,将有关系的云缩成一件物品

2.01背包选出最优方案

 

【心路历程】

这道题嘛,我之前看过一模一样的,就这个,ybtoj1898骑上彩虹。

唉,退钱!

 

【代码】

#include <bits/stdc++.h>
using namespace std;
int n,m,w;
const int maxn=100005;
int c[maxn],d[maxn];
int f[maxn];
int a[maxn];
int u[maxn],v[maxn];
int dp[maxn];
int ans=0;
struct New
{
    int wei,pri,num;
}q[maxn];

int find(int x)
{
    if(f[x]==x) return x;
    return f[x]=find(f[x]);
 } 
 
void merge(int x,int y)
{
    int k=find(x),w=find(y);
    if(k!=w ) 
    {
        f[k]=w;
    }
}

int main()
{
    scanf("%d %d %d",&n,&m,&w);
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d",&c[i],&d[i]);
     } 
    for(int i=1;i<=n;i++)
    {
        f[i]=i;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&u[i],&v[i]);
        merge(u[i],v[i]);
    } 
    for(int i=1;i<=n;i++)
    {
        if(find(i)!=i)//元素属于其他集合 
        {
            c[find(i)]+=c[i];
            d[find(i)]+=d[i];
            c[i]=d[i]=-1;
        }
    }
    
    for(int i=1;i<=n;i++)
    {
        if(c[i]>0&&d[i]>0)
        {
            ans++;
            q[ans].wei=d[i];
            q[ans].pri=c[i];
            q[ans].num=ans;
         } 
        
    }
/*    for(int i=1;i<=ans;i++)
    {
        printf("%d %d %d\n",q[i].num,q[i].pri,q[i].wei);
    }*/
    for(int i=1;i<=ans;i++)
    {
            for(int j=w;j>=q[i].pri;j--)
            {
                dp[j]=max(dp[j],dp[j-q[i].pri]+q[i].wei);    
            }
         } 
    
    printf("%d",dp[w]);
    return 0;
    
}

江湖再见啦!

posted @ 2021-08-27 10:55  TheZealous  阅读(54)  评论(0编辑  收藏  举报