csu 1326 The contest
裸的 并查集 + 分组背包;
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<stdio.h> 5 #include<cmath> 6 #include<vector> 7 using namespace std; 8 9 vector<int>vv[1002]; 10 vector<int>ss[1002]; 11 int f[1002],N,M,W,wi[1002],pi[1002],dp[1012]; 12 int find( int x ){ 13 if( x != f[x] )return f[x] = find(f[x]); 14 return x; 15 } 16 void inint( ){ 17 memset( dp,0,sizeof(dp) ); 18 for( int i = 0; i <= N; i++ ) f[i] = i; 19 for( int i = 0; i <= N; i++ )vv[i].clear(); 20 for( int i = 0; i <= N; i++ )ss[i].clear(); 21 for( int j = 1; j <= N; j++ ) 22 scanf("%d%d",&pi[j],&wi[j]); 23 } 24 int main( ) 25 { 26 while( scanf("%d%d%d",&N,&W,&M) != EOF ) 27 { 28 inint( ); 29 for( int i = 1; i <= M; i++ ) 30 { 31 int u,v; scanf("%d%d",&u,&v); 32 u = find( u ); v = find( v ); 33 if( u != v )f[u] = v; 34 } 35 for( int i = 1; i <= N; i++ ) 36 vv[find(i)].push_back(i); 37 int k = 0; 38 for( int i = 1; i <= N; i++ ) 39 { 40 int len = vv[i].size(); 41 if( len == 0 )continue; k++; 42 for( int j = 0; j < len; j++ ) 43 ss[k].push_back(vv[i][j]); 44 } 45 for( int i = 1; i <= k; i++ ) // 这里是分组背包; 46 for( int j = W; j >= 0; j-- ) 47 for( int t = 0; t < ss[i].size( ); t++ ) 48 if( j >= wi[ss[i][t]] ) 49 dp[j] = max( dp[j],dp[j - wi[ss[i][t]]] + pi[ss[i][t]] ); 50 cout<<dp[W]<<endl; 51 } 52 return 0; 53 }