其他分享
首页 > 其他分享> > 经商

经商

作者:互联网

原题链接
https://ac.nowcoder.com/acm/problem/14545

思路
先用并查集维护一下所有从1能走到的点,每次给出两个点,就将这两个点的祖宗节点维护,最后对于所有的1到n号点,用01背包做一次,只要祖宗节点和1号点一样,就代表能走到,就可以放到背包考虑。

代码

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 10010, M = 510;

int p[N];
int f[M];  // 表示考虑第i个人能获得的最大利益
int w[N], v[N];

int find(int x)
{
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int main()
{
    int t;
    cin >> t;
    while (t -- )
    {
        memset(f, 0, sizeof f);
        
        int n, m, c;
        cin >> n >> m >> c;
        for (int i = 1; i <= n; i ++ ) p[i] = i;
        
        for (int i = 2; i <= n; i ++ ) cin >> v[i] >> w[i];
        for (int i = 1; i <= m; i ++ )
        {
            int a, b;
            cin >> a >> b;
            a = find(a), b = find(b);
            if (a != b) p[b] = a;
        }
        
        for (int i = 2; i <= n; i ++ )
        {
            if (find(i) == find(1))  // 写find因为1可能被加到别的点后面
                for (int j = c; j >= v[i]; j -- )
                    f[j] = max(f[j], f[j - v[i]] + w[i]);
        }
        
        cout << f[c] << endl;
    }
    
    return 0;
}

标签:int,经商,cin,--,include,find,号点
来源: https://www.cnblogs.com/lautoh/p/14700987.html