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

 

你可能感兴趣的:(并查集)