P2515 [HAOI2010] 软件安装


:::若 add(0,i) 会影响缩点
:::add2-> 缩点 (单个点 也可以是 缩点 ) 然后构造0 ->构造树
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------debug\n"); using namespace std; const int maxn=1e3+10; int w[maxn],v[maxn],d[maxn]; int head1[maxn],to1[maxn<<1],nxt1[maxn<<1],tot1,head2[maxn],to2[maxn<<1],nxt2[maxn<<1],tot2; int dfn[maxn],low[maxn],dfstm,st[maxn],top,co[maxn],col; int rd[maxn],val[maxn],cost[maxn],f[maxn][maxn]; int n,m; void add1(int u,int v){ to1[++tot1]=v;nxt1[tot1]=head1[u];head1[u]=tot1;//!!!!!!! to->v } void add2(int u,int v){ to2[++tot2]=v;nxt2[tot2]=head2[u];head2[u]=tot2; } void tarjan(int u) { dfn[u]=low[u]=++dfstm; st[++top]=u; for(int i=head1[u];i;i=nxt1[i]) { int v=to1[i]; if(dfn[v]==0){ tarjan(v); low[u]=min(low[u],low[v]); } else if(co[v]==0) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { co[u]=++col; while(st[top]!=u){ co[st[top]]=col; top--; } top--; } } void dfs(int u)//树形结构 单向边 不需要 judge faa { for(int i=cost[u];i<=m;i++) f[u][i]=val[u]; for(int i=head2[u];i;i=nxt2[i]) { int v=to2[i]; dfs(v); for(int j=m;j>=0;j--){ for(int k=0;k<=j-cost[u];k++){ f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]);//f[u][j-k]已经推出来 了 } } } } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) cin>>w[i]; for(int i=1;i<=n;i++) cin>>v[i]; for(int i=1;i<=n;i++){ cin>>d[i]; if(d[i]!=0) add1(d[i],i); } for(int i=1;i<=n;i++) if(dfn[i]==0) tarjan(i); for(int i=1;i<=n;i++){ val[co[i]]+=v[i],cost[co[i]]+=w[i];//!!!!!!!!+= if(co[i]!=co[d[i]]&&d[i]!=0){//若 add(0,i) 会影响缩点 add2(co[d[i]],co[i]);//add2-> 缩点 (单个点 也可以是 缩点 ) 然后构造0 ->构造树 rd[co[i]]++; } } val[0]=0,cost[0]=0; for(int i=1;i<=col;i++) if(rd[i]==0) add2(0,i); //ddd dfs(0); //for(int i=1;i<=n;i++) cout<<i<<"->"<<co[i]<<"->"<<rd[co[i]]<<endl; cout<<f[0][m]<<'\n';//<- add2 + dfs return 0; }

浙公网安备 33010602011771号