其他分享
首页 > 其他分享> > 2021.9.114考试总结[NOIP模拟53]

2021.9.114考试总结[NOIP模拟53]

作者:互联网

T1 ZYB和售货机


容易发现把每个物品都买成$1$是没有影响的。

然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以建出每个点出度入度都是$1$的图。

把所有边都连上是一个基环树,所以建出的若干个联通图中只有一个环。而我们要做的工作就是用最小代价把这个环断掉,形成的树上所有边都可以对答案贡献。

记每个物品的最大获利和次大获利,在图上$DFS$,每到一个点先加上最大获利,记录路径上最大获利与次大获利差的最小值,如果当前这一块是环,把答案减去这个最小值即可。

$code:$

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 
 5 namespace IO{
 6     inline int read(){
 7         char ch=getchar(); int x=0,f=1;
 8         while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
 9         while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
10         return x*f;
11     }
12     inline void write(int x,char sp){
13         char ch[20]; int len=0;
14         if(x<0){ putchar('-'); x=~x+1; }
15         do{ ch[len++]=x%10+(1<<4)+(1<<5); x/=10; }while(x);
16         for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
17     }
18     inline int max(int x,int y){ return x<y?y:x; }
19     inline int min(int x,int y){ return x<y?x:y; }
20     inline void swap(int &x,int &y){ x^=y^=x^=y; }
21     inline void chmax(int &x,int y){ x=x<y?y:x; }
22     inline void chmin(int &x,int y){ x=x<y?x:y; }
23 } using namespace IO;
24 
25 const int NN=1e6+5;
26 int n,st,ans,cnt,mn,bel[NN],f[NN],c[NN],d[NN],a[NN],mx[NN],sc[NN],val[NN];
27 bool vis[NN];
28 
29 void dfs(int x){
30     if(bel[x]==cnt) return ans-=mn,void();
31     if(bel[x]) return;
32     if(!mx[x]) return;
33     bel[x]=cnt;
34     ans+=val[mx[x]]*a[x];
35     chmin(mn,val[mx[x]]-val[sc[x]]);
36     if(mx[x]!=x)dfs(mx[x]);
37 }
38 signed main(){
39     freopen("goods.in","r",stdin);
40     freopen("goods.out","w",stdout);
41     n=read();
42     for(int i=1;i<=n;i++)
43         f[i]=read(), c[i]=read(), d[i]=read(), a[i]=read();
44     for(int i=1;i<=n;i++){
45         val[i]=d[f[i]]-c[i];
46         if(val[i]>val[mx[f[i]]]) sc[f[i]]=mx[f[i]], mx[f[i]]=i;
47         else if(val[i]>val[sc[f[i]]]) sc[f[i]]=i;
48     }
49     for(int i=1;i<=n;i++)
50         if(!bel[i]) ++cnt,mn=INT_MAX,dfs(i);
51     write(ans,'\n');
52     return 0;
53 }
T1

 

标签:ch,NOIP,2021.9,获利,物品,int,53,sc,mx
来源: https://www.cnblogs.com/keeeeeeen/p/15270590.html