题目链接:https://www.luogu.org/problemnew/show/P1455
一句话题目做法:并查集合并+01背包
启示:要每次再find一遍。路径压缩会快。因为合并的时候如果是1连3,3连2,4连2,最后也不能保证一步就能连到fa上去。
结果会是fa[2] = fa[3] = fa[4] = 2.
fa[1] = 3.
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 10010; 6 int n,m,money,fa[maxn];//n朵云,m个搭配,w现有钱的数目 7 int qwqw[maxn],f[maxn],qwqc[maxn],w[maxn],c[maxn]; 8 int find(int x) 9 { 10 return x==fa[x]?x:fa[x]=find(fa[x]); 11 } 12 int unionn(int x, int y) 13 { 14 15 } 16 int main() 17 { 18 scanf("%d%d%d",&n,&m,&money); 19 20 for(int i = 1; i <= n; i++) 21 fa[i] = i; 22 23 for(int i = 1; i <= n; i++) 24 { 25 int fee,d; 26 scanf("%d%d",&fee,&d); 27 w[i] = fee; c[i] = d; 28 } 29 for(int i = 1; i <= m; i++) 30 { 31 int u,v; 32 scanf("%d%d",&u,&v); 33 int x = find(u); 34 int y = find(v); 35 if(x!=y) 36 fa[y] = x; 37 } 38 39 for(int i = 1; i <= n; i++) 40 { 41 if(fa[i]!=i) 42 { 43 c[find(i)] += c[i]; 44 w[find(i)] += w[i]; 45 c[i] = 0; w[i] = 0; 46 } 47 } 48 49 for(int i = 1; i <= n; i++) 50 for(int v = money; v >= w[i]; v--) 51 f[v] = max(f[v],f[v-w[i]]+c[i]); 52 printf("%d",f[money]); 53 return 0; 54 }