题目描述
任务一:
有n个人,每个人只能选一次,会消耗a[i]精力得到b[i]收益,现有的精力值为C,求可以到达的最大收益
思路
这么看就是一个简单的01背包问题(用一维的话注意从大到小枚举c(精力))
任务二
这n个人之间存在友谊关系,我们只能选择跟1有关系的人,
思路
用简单的并查集维护,在01任务1求解的时候判断

    if(find(i)!=1) continue;

代码

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdio>
#include <bitset>
#include <vector>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define UpMing main
#define re register
#pragma GCC optimize(2)
#define Accept return 0;
#define lowbit(x) ((x)&(-(x)))
#define mst(x, a) memset( x,a,sizeof(x) )
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int inf =0x3f3f3f3f;
const int maxn=2e5+7;
const ll mod = 1e9+7;
const int N =1e6+3;
inline ll read() {
    ll  x=0;
    bool f=0;
    char ch=getchar();
    while (ch<'0'||'9'<ch)    f|=ch=='-', ch=getchar();
    while ('0'<=ch && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return f?-x:x;
}
void out(ll x) {
    int stackk[20];
    if(x<0) {
        putchar('-');
        x=-x;
    }
    if(!x) {
        putchar('0');
        return;
    }
    int top=0;
    while(x) stackk[++top]=x%10,x/=10;
    while(top) putchar(stackk[top--]+'0');
}
ll n,m,c,a[maxn],b[maxn],p[maxn],dp[maxn];
ll find(ll x) {
    if(x==p[x]) return x;
    return p[x]=find(p[x]);
}
int UpMing() {
    ll toto=read();
    while(toto--) {
        n=read();
        m=read();
        c=read();
        for(int i=1 ; i<=1e5 ; i++)
            a[i]=b[i]=dp[i]=0,p[i]=i;
        for(int i=2 ; i<=n ; i++) {
            a[i]=read();
            b[i]=read();
        }
        for(int i=1 ; i<=m ; i++) {
            ll x=read();
            ll y=read();
            ll dx=find(x);
            ll dy=find(y);
            if(dx>dy) swap(dx,dy);
            if(dx!=dy)
                p[dy]=dx;
        }
        for(int i=2 ; i<=n ; i++) {
            if(find(i)!=1) continue;
            for(int j=c ; j>=a[i]; j--) {
                dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
            }
        }
        out(dp[c]);
        cout<<endl;
    }
    Accept;
}