CF741B Arpa's weak amphitheater and Mehrdad's valuable Hoses

Posted by johng on Mon, 30 Sep 2019 15:15:55 +0200

Address of Luo Valley


After reading this question, we can see that the following sentence for a circle of friends, either choose one of them or choose all, it is easy to think of the group backpack, then the next consideration is
How to Transform the Form of Component Backpack

Obviously, we can maintain every circle of friends by using and collecting them. So for each circle of friends, we should set up a vector to maintain the people in the circle of friends. At the same time, we should treat everyone as a person, join the circle of friends, and then make a 01 knapsack in the circle. Note that if a person has no friends, then his circle of friends does not need to add another person, otherwise. That person will appear twice.

And because you want to add everyone to the array, the array needs to be opened a little bit larger than the data.
CodeCodeCode

#include<bits/stdc++.h>

#define N 5001
#define ll long long
 
using namespace std;

inline void read(ll &s){
	s = 0; ll w = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') w = -1, ch = getchar();}
	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
	s *= w; return ;
}
struct node{
	int x, y;
}e[N];

ll f[N], fa[N], a[N], b[N];
ll n, m, w, p;
vector<ll> group[N];

inline ll get(ll x){
	return fa[x] == x ? x : fa[x] = get(fa[x]);
}

int main()
{
	read(n), read(m), read(w);
	p = n;
	
	for(ll i = 1; i <= n; ++i) fa[i] = i, read(a[i]);
	
	for(ll i = 1; i <= n; ++i) read(b[i]);
	
	for(ll i = 1; i <= m; ++i){
		ll x, y;
		read(x), read(y);
		x = get(x), y = get(y);
		if(x != y) fa[y] = x;
	}
	
	for(ll i = 1; i <= n; ++i) group[get(i)].push_back(i);
	
	for(ll i = 1; i <= n; ++i){
		if(group[i].size() <= 1) continue;
		group[i].push_back(++p);
		for(ll j = 0; j < group[i].size() - 1; ++j)
			a[p] += a[group[i][j]], b[p] += b[group[i][j]];
	}
	
	for(ll k = 1; k <= n; ++k){
		if(!group[k].size()) continue;
		
		for(ll j = w; j >= 0; --j)
			for(ll i = 0; i < group[k].size(); ++i){
				ll x = group[k][i];
				if(j >= a[x]) f[j] = max(f[j], f[j - a[x]] + b[x]);
			}
	}
	
	printf("%d\n", f[w]);
	
	return 0;
}