CSU1326+背包+并查集
先预处理出有多少个任务即可
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 using namespace std; 7 const int maxn = 1005; 8 const int maxm = 1000005; 9 struct Edge{ 10 int u,v,next; 11 }edge[ maxm ]; 12 int cnt ,head[ maxn ]; 13 void init(){ 14 cnt = 0; 15 memset( head,-1,sizeof( head ) ); 16 } 17 void addedge( int a,int b ){ 18 edge[ cnt ].u = a; 19 edge[ cnt ].v = b; 20 edge[ cnt ].next = head[ a ]; 21 head[ a ] = cnt ++; 22 } 23 int fa[ maxn ],root[ maxn ],dp[ maxn ]; 24 int val[ maxn ],cost[ maxn ]; 25 int find( int x ){ 26 if( x==fa[x] ) return x; 27 else return fa[x] = find( fa[x] ); 28 } 29 int main(){ 30 int n,Max,k; 31 while( ~scanf("%d%d%d",&n,&Max,&k) ){ 32 for( int i=1;i<=n;i++ ){ 33 scanf("%d%d",&val[i],&cost[i]); 34 fa[ i ] = i; 35 } 36 init(); 37 memset( dp,0,sizeof( dp ) ); 38 memset( root,0,sizeof( root ) ); 39 while( k-- ){ 40 int a,b; 41 scanf("%d%d",&a,&b); 42 int x = find(a); 43 int y = find(b); 44 if( fa[x]!=y ){ 45 fa[x] = y; 46 } 47 } 48 int r = 1; 49 for( int i=1;i<=n;i++ ){ 50 int x = find( i ); 51 if( root[x]==0 ){ 52 root[x] = r++; 53 } 54 addedge( root[x],i ); 55 } 56 for( int i=1;i<r;i++ ){ 57 for( int j=Max;j>=0;j-- ){ 58 for( int k=head[i];k!=-1;k=edge[k].next ){ 59 int nxt = edge[k].v; 60 if( j>=cost[nxt] ){ 61 dp[j] = max( dp[j],dp[j-cost[nxt]]+val[nxt] ); 62 } 63 } 64 } 65 } 66 printf("%d\n",dp[Max]); 67 } 68 return 0; 69 }
keep moving...