每个联通块看成一个整体,然后做个背包就好啦。
1 #include<cstdio> 2 #define N 10001 3 #define repu(i,x,y) for(i=x;i<=y;i++) 4 #define max(a,b) (a>b?a:b) 5 struct edge{ 6 int v; 7 edge *next; 8 }e[N],*tp=e,*first[N]; 9 int d[N],c[N],w[N],sc[N],sw[N],f[N],x=0; 10 void add(int u,int v) { 11 *tp=(edge){v,first[u]}; first[u]=tp++; 12 *tp=(edge){u,first[v]}; first[v]=tp++; 13 } 14 void dfs(int u,int fa) { 15 d[u]=x; sc[x]+=c[u]; sw[x]+=w[u]; 16 for (edge *i=first[u];i;i=i->next) { 17 int v=i->v; 18 if (v!=fa) dfs(v,u); 19 } 20 } 21 int main() { 22 int i,j,n,m,u,v,W,ans=0; scanf("%d%d%d",&n,&m,&W); 23 repu(i,1,n) scanf("%d%d",&c[i],&w[i]); 24 repu(i,1,m) scanf("%d%d",&u,&v),add(u,v); 25 repu(i,1,n) 26 if (!d[i]) ++x,dfs(i,0); 27 repu(i,1,x) 28 for (j=W;j>=0;j--) if (j-sc[i]>=0) 29 f[j]=max(f[j],f[j-sc[i]]+sw[i]),ans=max(ans,f[j]); 30 printf("%d\n",ans); 31 }
时间: 2024-10-23 22:23:46