首页 > 其他 > 详细

7.12训练日志

时间:2019-07-12 16:35:03      阅读:66      评论:0      收藏:0      [点我收藏+]

今天早上起来状态不如昨天,上来就做软件安装:

I. 软件安装

 
题目类型:传统 评测方式:文本比较
 

题目描述

现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一 些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大)。

但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j)。幸运的 是,一个软件最多依赖另外一个软件。如果一个软件不能正常工作,那么它能够发挥的作用为0。

我们现在知道了软件之间的依赖关系:软件i依赖软件Di。现在请你设计出一种方案,安装价值尽量大的软件。一个软件只能被安装一 次,如果一个软件没有依赖则Di=0,这时只要这个软件安装了,它就能正常工作。

输入格式

第1行:N,M (0<=N<=100.0<=M<=500)

第2行:W1,W2,…,Wi,…,Wn(0<=Wi<=M)

第3行:V1,V2,…,Vi,…,Vn(0<=Vi<=1000)

第4行:D1,D2,…,Di,…,Dn(0<=Di<=N,Di≠i)

输出格式

一个整数,代表最大价值。

样例

样例输入

3 10
5 5 6
2 3 4
0 1 1

样例输出

5

这题上来就知道是反向建边,然后跑树批(树上dp)然后就开始码,并没有看标签,以为这就是上天赐予的水题,满怀信心要AC他,dp式子也写对了,也建虚根节点了,然而

惊喜爆10,一看标签,省选,靠,不是水题(宝宝不开心!)然后就想了一想,自己又手膜了一个样例然后就发现会出现环,例如1 3 2 1时就会出现环,所以需要什么?

tarjin(orz)缩点啊,然后,然后就A了;

码:

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<stack>
 6 using namespace std;
 7 #define LL long long
 8 //powered by lsc;
 9 const LL maxn=8000;
10 LL head[maxn],ver[maxn],nxt[maxn],tot,d[maxn],cntt;
11 struct chu{
12 LL x,y,head,nxt;
13 }s[maxn];                //edge;
14 
15 LL w[maxn],v[maxn],dp[3000][3000];
16 LL n,m,ans;            //problom;
17 
18 LL dfn[maxn],low[maxn],belong[maxn],cp[maxn],cnt,vis[maxn],cw[maxn];//cp is the v value,cw is the w value;
19 stack<LL>ss;
20 inline void add(LL x,LL y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
21 inline void ADD(LL x,LL y){s[++cntt].y=y;s[cntt].x=x;s[cntt].nxt=s[x].head;s[x].head=cntt;}
22 void dfs(LL x)
23 {
24     dfn[x]=low[x]=++cnt;
25     ss.push(x);
26     vis[x]=1;
27     for (LL i=s[x].head;i;i=s[i].nxt)
28         if (!dfn[s[i].y])
29             dfs(s[i].y),
30             low[x]=min(low[x],low[s[i].y]);
31         else if (vis[s[i].y])
32             low[x]=min(low[x],dfn[s[i].y]);
33     if (dfn[x]==low[x])
34     {
35         cp[x]=0;LL ress=0;
36         for (LL y=-1;y!=x;y=ss.top(),ss.pop())
37         {
38             belong[ss.top()]=x,
39             cp[x]+=v[ss.top()],
40             cw[x]+=w[ss.top()],
41             vis[ss.top()]=0;
42         }
43     }
44 }
45 void solve(LL x,LL fa)
46 {
47     for(LL i=cw[x];i<=m;i++)
48         dp[x][i]=cp[x];
49     for(LL i=head[x];i;i=nxt[i])
50     {
51         LL y=ver[i];
52         if(y==fa)continue;solve(y,x);
53         for(LL o=m-cw[x];o>=0;o--)
54             for(LL u=0;u<=o;u++)
55             dp[x][o+cw[x]]=max(dp[x][o+cw[x]],dp[y][u]+dp[x][o+cw[x]-u]);
56     }
57 }
58 int main()
59 {
60     //freopen("cnm.txt","r",stdin);
61     scanf("%lld%lld",&n,&m);
62     for(LL i=1;i<=n;i++)
63     scanf("%lld",&w[i]);
64     for(LL i=1;i<=n;i++)
65     scanf("%lld",&v[i]);
66     for(LL i=1;i<=n;i++){LL vp=0;scanf("%lld",&vp);if(vp==0)continue;ADD(vp,i);}
67     //for(LL i=1;i<=n;i++)if(d[i]==0)ADD(0,i);    //xu root;
68     for(LL i=1;i<=n;i++)if(!dfn[i])dfs(i);
69         for(LL j=1;j<=cnt;j++)
70         {
71             if(belong[s[j].x]!=belong[s[j].y])
72                 //printf("%d %d  start point value:%d end point value:%d\n",belong[i],belong[s[j].y],cw[belong[i]],cw[belong[s[j].y]]),
73                 add(belong[s[j].x],belong[s[j].y]),
74                 d[belong[s[j].y]]++;
75         }
76     for(int i=1;i<=n;i++)if(d[i]==0)add(0,i);
77     solve(0,0);
78     printf("%lld\n",dp[0][m]);
79     return 0;
80 }
T1

//////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////未完待更///////////////////////////////////////////////////////////////////

 

7.12训练日志

原文:https://www.cnblogs.com/hzoi-lsc/p/11176107.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!