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 }
View Code

 

posted on 2013-10-06 00:19  浪舟  阅读(161)  评论(0编辑  收藏  举报

导航