[HAOI2010]软件安装
Posted al-ca
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HAOI2010]软件安装相关的知识,希望对你有一定的参考价值。
[HAOI2010]软件安装
开始没有看懂题,以为就是个树形依赖背包,打完之后W40,然后才发现它会有还,要用tarjan缩完点后跑背包,要建立一个虚拟节点0连接所有的子图(注意连接的位置)。
但是有个细节卡了我好长时间:
错误示范:
1 for(int i=1;i<=n;i++)//这样会导致0连接的不是入度为0的点(或环) 2 if(!Dsn[i]) 3 4 tarjan(i); 5 add(0,i); 6
正确代码:
1 for(int i=1;i<=tot;i++) 2 if(!du[i]) 3 add2(0,i);
在缩点是记录每个scc的入度,0直接和入度为0的scc连接。
#include<iostream> #include<cstring> #include<cstdio> #include<vector> #define MAXN 110 #define ma(x) memset(x,0,sizeof(x)) using namespace std; struct edge int u,v,nxt; #define u(x) ed[x].u #define v(x) ed[x].v #define n(x) ed[x].nxt #define u2(x) ed2[x].u #define v2(x) ed2[x].v #define n2(x) ed2[x].nxt ed[5010],ed2[5010]; int first[MAXN],num_e; #define f(x) first[x] int first2[MAXN],num_e2; #define f2(x) first2[x] int n,m; int w[MAXN],v[MAXN],d[MAXN]; int w2[MAXN],v2[MAXN]; int Dsn[MAXN],Low[MAXN],cnt; int stack[MAXN],top; bool vi[MAXN]; int belong[MAXN],tot; int du[MAXN]; vector<int> scc[MAXN]; void tarjan(int x) Dsn[x]=++cnt;Low[x]=cnt; stack[++top]=x; vi[x]=1; for(int i=f(x);i;i=n(i)) if(!Dsn[v(i)])tarjan(v(i)),Low[x]=min(Low[x],Low[v(i)]); else if(vi[v(i)])Low[x]=min(Low[x],Low[v(i)]); if(Dsn[x]==Low[x]) ++tot;vi[x]=0; while(stack[top]!=x) vi[stack[top]]=0; scc[tot].push_back(stack[top]); belong[stack[top--]]=tot; scc[tot].push_back(stack[top]); belong[stack[top--]]=tot; inline void add(int u,int v) ++num_e; u(num_e)=u; v(num_e)=v; n(num_e)=f(u); f(u)=num_e; inline void add2(int u,int v) ++num_e2; u2(num_e2)=u; v2(num_e2)=v; n2(num_e2)=f2(u); f2(u)=num_e2; int f[MAXN][510]; void dfs(int x) f[x][w2[x]]=v2[x]; for(int i=f2(x);i;i=n2(i)) dfs(v2(i)); for(int j=m;j>=w2[x];j--) for(int k=0;k<=m;k++) if(j+k>m)break; f[x][j+k]=max(f[x][j+k],f[x][j]+f[v2(i)][k]); signed main() // freopen("in.txt","r",stdin); cin>>n>>m; for(int i=1;i<=n;i++)scanf("%d",&w[i]); for(int i=1;i<=n;i++)scanf("%d",&v[i]); for(int i=1;i<=n;i++)scanf("%d",&d[i]);if(d[i])add(d[i],i); for(int i=1;i<=n;i++) if(!Dsn[i]) tarjan(i); for(int i=1;i<=num_e;i++) if(belong[u(i)]!=belong[v(i)]) add2(belong[u(i)],belong[v(i)]); du[belong[v(i)]]++; for(int i=1;i<=tot;i++) if(!du[i]) add2(0,i); for(int i=1;i<=tot;i++) for(int j=0;j<scc[i].size();j++) w2[i]+=w[scc[i][j]]; v2[i]+=v[scc[i][j]]; dfs(0); int ans=0; for(int i=1;i<=m;i++)ans=max(ans,f[belong[0]][i]); printf("%d\n",ans);
以上是关于[HAOI2010]软件安装的主要内容,如果未能解决你的问题,请参考以下文章