客观上说,这道题是并查集和01背包问题的基础题
#include<bits\stdc++.h>
using namespace std;
namespace mySTL{
class UF{//real size is bigger
private:
int size;
int *arr;
int *weight;
int num_sets;
public:
UF(int Nsize):size(Nsize),num_sets(Nsize){//in fact,realsize=1+Nsize
arr=new int [size+1];//real size is bigger
weight=new int [size+1];//tree root size
for(int i=1;i<=size;++i){
arr[i]=i;
weight[i]=1;
}
}
~UF(){
if(arr!=nullptr){
delete[] arr;
}
if(weight!=nullptr){
delete[] weight;
}
}
int find(int i){
int now=i;
while(arr[now]!=now){//find root node
now=arr[now];
}//only index at root matters
return now;
}
void connect(int i,int j){
int iroot=find(i);
int jroot=find(j);
if(iroot!=jroot){
--num_sets;//one of roots has been removed
//determine which of roots to redirect
if(weight[iroot]==weight[jroot]){
arr[iroot]=jroot;
weight[jroot]+=1;
}else if(weight[iroot]<weight[jroot]){
arr[iroot]=jroot;
}else{
arr[jroot]=iroot;
}
}
}
bool isSame(int i,int j){
return find(i)==find(j);
}
int countSets(){
return num_sets;
}
};
}
#define MAXMEN 10005
struct person{
int cost,profit;
}peo[MAXMEN];
int inputAndGetAccess(int N,int M){
for(int iN=2;iN<=N;++iN){
cin>>peo[iN].cost>>peo[iN].profit;
}
mySTL::UF nowUF(N);
int temx,temy;
for(int iM=1;iM<=M;++iM){
cin>>temx>>temy;
nowUF.connect(temx,temy);
}
int newlen=0;
peo[0]=peo[1];//change to make it easier.
int root1=nowUF.find(1);
for(int i=2;i<=N;++i){
if(nowUF.find(i)==root1){
peo[newlen++]=peo[i];
}
}
return newlen;
}
#define MAXC 510
int dp[2][MAXC];
int _01back(int plen,int C){
memset(dp,0xcf,sizeof(dp));
dp[0][0]=0;
for(int i=0;i<plen;++i){
for(int jc=0;jc<=C;++jc){
dp[(i+1)&1][jc]=dp[i&1][jc];
}//copy now info
for(int mayPutIndex=peo[i].cost;mayPutIndex<=C;++mayPutIndex){
if(dp[(i+1)&1][mayPutIndex]<dp[i&1][mayPutIndex-peo[i].cost]+peo[i].profit){
dp[(i+1)&1][mayPutIndex]=dp[i&1][mayPutIndex-peo[i].cost]+peo[i].profit;
}
}
}
int ans=0;
for(int j=0;j<=C;++j){
if(ans<dp[plen&1][j]){
ans=dp[plen&1][j];
}
}
return ans;
}
int main(){
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T;
cin>>T;
while(T--){
int N,M,C;
cin>>N>>M>>C;
int plen=inputAndGetAccess(N,M);
//now become a 01 back problem
int ans=_01back(plen,C);
cout<<ans<<endl;
}
}