1. 程式人生 > >哈爾濱理工大學第七屆程式設計競賽初賽(高年級組)D-經商

哈爾濱理工大學第七屆程式設計競賽初賽(高年級組)D-經商

連結:https://www.nowcoder.com/acm/contest/27/D
來源:牛客網

題目描述

小d是一個搞房地產的土豪。每個人經商都有每個人經商的手段,當然人際關係是需要放在首位的。

小d每一個月都需要列出來一個人際關係表,表示他們搞房地產的人的一個人際關係網,但是他的精力有限,對應他只能和能夠接觸到的人交際。比如1認識2,2認識3,那麼1就可以接觸3進行交際,當然1和2也可以交際。

小d還很精明,他知道他和誰交際的深獲得的利益大,接下來他根據自己的想法又列出來一個利益表,表示他和這些人交際需要耗用多少精力,能夠獲得的利益值為多少。

小d想知道,他在精力範圍內,能夠獲得的利益值到底是多少。

設定小d自己的編號為1.並且對應一個人的交際次數限定為1.

輸入描述:

本題包含多組輸入,第一行輸入一個數t,表示測試資料的組數
每組資料的第一行輸入三個數,N,M,C,表示這個人際關係網一共有多少個人,關係網的關係數,以及小d的精力值
接下來N-1行,每行兩個數ai,bi。這裡第i行表示和編號為i+1的人認識需要花費ai的精力,能夠獲得的利益值為bi。
再接下來M行,每行兩個數x,y,表示編號為x的人能夠和編號為y的人接觸
t<=50
2<=N<=10000
1<=M<=10*N
1<=ai,bi<=10
1<=C<=500
1<=x,y<=N

輸出描述:

輸出包含一行,表示小d能夠獲得的最大利益值
題解:
用並查集找出可以形成關係的,然後揹包求解。

程式碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=10007;
int par[maxn],costn[maxn],valn[maxn],cost[maxn],val[maxn],dp[505];
void init()
{
    for(int i=0;i<maxn;i++)
        par[i]=i;
}
int find(int x)
{
    if(x==par[x])return x;
    return par[x]=find(par[x]);
}
void unite(int x,int y)
{
    x=find(x);y=find(y);
    if(x!=y)
        par[x]=y;
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        init();
        int n,m,c;scanf("%d%d%d",&n,&m,&c);
        for(int i=2;i<=n;i++)
            scanf("%d%d",&costn[i],&valn[i]);
        while(m--)
        {
            int x,y;scanf("%d%d",&x,&y);
            unite(x,y);
        }
        int t=0;
        for(int i=2;i<=n;i++)
        {
            if(find(1)==find(i))
            {
                cost[++t]=costn[i];
                val[t]=valn[i];
            }
        }
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=t;i++)
        {
            for(int j=c;j>=cost[i];j--)
                dp[j]=max(dp[j],dp[j-cost[i]]+val[i]);
        }
        printf("%d\n",dp[c]);
    }
    return 0;
}