
1 #include<cstdio> 2 #define maxn 1005 3 #include<cstring> 4 #include<math.h> 5 #include<iostream> 6 using namespace std; 7 8 9 int f[maxn],v[maxn],p[maxn],numcount; 10 int F[maxn]; 11 bool vis[maxn*100]; 12 int n,w,k,a,b; 13 14 int maxx(int a,int b) 15 { 16 if (a>=b) return a;else return b; 17 } 18 int find(int x){ 19 if(x==f[x]) return x; 20 int y=find(f[x]); 21 f[x]=y; 22 return y; 23 } 24 void merge(int a,int b){ 25 int ra=find(a); 26 int rb=find(b); 27 if(ra!=rb) f[ra]=rb; 28 return ; 29 } 30 void PacketBackpack() 31 { 32 memset(F,0,sizeof(F)); 33 int tot=0; 34 while(1) 35 { 36 int mark; 37 for(int i=1;i<=n;i++) 38 { 39 if (f[i]>0) {mark=f[i];break;} 40 } 41 for(int vv=w;vv>=0;vv--) 42 { 43 for(int j=1;j<=n;j++) 44 { 45 if (f[j]!=mark) continue; 46 if(vv-p[j]>=0)F[vv]=maxx(F[vv],F[vv-p[j]]+v[j]); 47 } 48 } 49 for(int k=1;k<=n;k++) 50 { 51 if (f[k]==mark) {f[k]=0;tot++;} 52 } 53 if (tot==n) break; 54 } 55 printf("%d ",F[w]); 56 return; 57 } 58 int main() 59 { 60 while(scanf("%d%d%d",&n,&w,&k)!=EOF)//N题,w容量 61 { 62 int cnt=0; 63 for(int i=1;i<=n;i++)f[i]=i; 64 numcount=0; 65 for(int i=1;i<=n;i++) 66 scanf("%d%d",&v[i],&p[i]);//得分,体力 67 for(int i=0;i<k;i++) 68 { 69 scanf("%d%d",&a,&b); 70 merge(a,b); 71 } 72 for(int i=1;i<=n;i++) 73 { 74 int x=find(i); 75 if(!vis[x]){vis[x]=1;cnt++;}//组数 76 } 77 PacketBackpack(); 78 } 79 return 0; 80 }
模板题
Description
殷犇有很多队员。他们都认为自己是最强的,于是,一场比赛开始了~
于是安叔主办了一场比赛,比赛有n个题目,每个题目都有一个价值Pi和相对能力消耗Wi,但是有些题目因为太坑不能同时做出来,并且坑题具有传递性。(a和b一起做会坑、b和c会坑则a和c也会坑) ACM队员们想知道,于是他们想知道在能力范围内,它们最多可以作出多少价值的题目。
聪明的你,告诉我,能帮帮他们吗?
Input
第1行两个整数,n,Wmax,k(0<=n,Wmax,k<=1000),其中n为题目总数,Wmax为初始的总能力数.
接下来n行,为每个题目的Pi,Wi(0<=Pi<=1000,1<=Wi<=10,均为整数)
再接下来k行,每行2个数字a,b表示a和b会坑
Output
对每组数据输出1行为最大可能价值