[BZOJ5289][HNOI2018]排列(拓扑排序+pb_ds)

Posted HocRiser

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ5289][HNOI2018]排列(拓扑排序+pb_ds)相关的知识,希望对你有一定的参考价值。

 1 #include<cstdio>
 2 #include<queue>
 3 #include<algorithm>
 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 5 typedef long long ll;
 6 using namespace std;
 7 
 8 const int N=500100;
 9 int n,u,p,fa[N],tim,cnt,vis[N],f[N],sz[N],h[N],nxt[N<<1],to[N<<1];
10 ll ans,w[N];
11 struct D{ int u,sz; ll w; bool operator <(const D &b)const{ return w*b.sz>b.w*sz; } };
12 priority_queue<D>Q;
13 
14 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
15 
16 void dfs(int u){
17     vis[u]=1; tim++;
18     for (int i=h[u],v; i; i=nxt[i])
19         if (vis[v=to[i]]) { puts("-1"); exit(0); } else dfs(v);
20 }
21 
22 int get(int x){ return (f[x]==x) ? x : f[x]=get(f[x]); }
23 
24 int main(){
25     freopen("bzoj5289.in","r",stdin);
26     freopen("bzoj5289.out","w",stdout);
27     scanf("%d",&n);
28     rep(i,1,n) scanf("%d",&fa[i]),add(fa[i],i);
29     dfs(0); if (tim<=n) { puts("-1"); return 0; }
30     rep(i,0,n) f[i]=i,sz[i]=1;
31     rep(i,1,n) scanf("%lld",&w[i]),Q.push((D){i,1,w[i]});
32     while (!Q.empty()){
33         D s=Q.top(); Q.pop();
34         if (sz[u=get(s.u)]!=s.sz) continue;
35         f[u]=p=get(fa[u]); ans+=w[u]*sz[p];
36         w[p]+=w[u]; sz[p]+=sz[u];
37         if (p) Q.push((D){p,sz[p],w[p]});
38     }
39     printf("%lld\n",ans);
40     return 0;
41 }

 

 1 #include<cstdio>
 2 #include<set>
 3 #include<algorithm>
 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 5 typedef long long ll;
 6 using namespace std;
 7 
 8 const int N=500100;
 9 int n,u,p,fa[N],tim,cnt,vis[N],f[N],sz[N],h[N],nxt[N<<1],to[N<<1];
10 ll ans,w[N];
11 struct D{
12     int u,sz; ll w;
13     bool operator <(const D &b)const{ return (w*b.sz!=b.w*sz) ? w*b.sz<b.w*sz : ((u!=b.u)?u<b.u:(sz<b.sz)); }
14 };
15 multiset<D>Q;
16 
17 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
18 
19 void dfs(int u){
20     vis[u]=1; tim++;
21     for (int i=h[u],v; i; i=nxt[i])
22         if (vis[v=to[i]]) { puts("-1"); exit(0); } else dfs(v);
23 }
24 
25 int get(int x){ return (f[x]==x) ? x : f[x]=get(f[x]); }
26 
27 int main(){
28     freopen("bzoj5289.in","r",stdin);
29     freopen("bzoj5289.out","w",stdout);
30     scanf("%d",&n);
31     rep(i,1,n) scanf("%d",&fa[i]),add(fa[i],i);
32     dfs(0); if (tim<=n) { puts("-1"); return 0; }
33     rep(i,0,n) f[i]=i,sz[i]=1;
34     rep(i,1,n) scanf("%lld",&w[i]),Q.insert((D){i,1,w[i]});
35     while (!Q.empty()){
36         D s=*Q.begin(); Q.erase(s);
37         if (sz[u=get(s.u)]!=s.sz) continue;
38         f[u]=p=get(fa[u]); ans+=w[u]*sz[p];
39         w[p]+=w[u]; sz[p]+=sz[u];
40         if (p) Q.insert((D){p,sz[p],w[p]});
41     }
42     printf("%lld\n",ans);
43     return 0;
44 }

 

 1 #include<cstdio>
 2 #include<ext/pb_ds/assoc_container.hpp>
 3 #include<ext/pb_ds/priority_queue.hpp>
 4 #include<algorithm>
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 typedef long long ll;
 7 using namespace std;
 8 
 9 const int N=500100;
10 int n,u,p,fa[N],tim,cnt,vis[N],f[N],sz[N],h[N],nxt[N<<1],to[N<<1];
11 ll ans,w[N];
12 struct D{ int u; ll w; };
13 struct Cmp{
14     bool operator()(const D &a,const D &b)const
15     { return (a.w*sz[b.u]!=b.w*sz[a.u]) ? a.w*sz[b.u]>b.w*sz[a.u] : ((a.u!=b.u)?a.u>b.u:(sz[a.u]>sz[b.u])); }
16 };
17 __gnu_pbds::priority_queue<D,Cmp>Q;
18 __gnu_pbds::priority_queue<D,Cmp>::point_iterator its[N];
19 
20 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
21 
22 void dfs(int u){
23     vis[u]=1; tim++;
24     for (int i=h[u],v; i; i=nxt[i])
25         if (vis[v=to[i]]) { puts("-1"); exit(0); } else dfs(v);
26 }
27 
28 int get(int x){ return (f[x]==x) ? x : f[x]=get(f[x]); }
29 
30 int main(){
31     freopen("bzoj5289.in","r",stdin);
32     freopen("bzoj5289.out","w",stdout);
33     scanf("%d",&n);
34     rep(i,1,n) scanf("%d",&fa[i]),add(fa[i],i);
35     dfs(0); if (tim<=n) { puts("-1"); return 0; }
36     rep(i,0,n) f[i]=i,sz[i]=1;
37     rep(i,1,n) scanf("%lld",&w[i]),its[i]=Q.push((D){i,w[i]});
38     while (!Q.empty()){
39         int u=Q.top().u; Q.pop();
40         f[u]=p=get(fa[u]); ans+=w[u]*sz[p];
41         w[p]+=w[u]; sz[p]+=sz[u];
42         if (p) Q.modify(its[p],(D){p,w[p]});
43     }
44     printf("%lld\n",ans);
45     return 0;
46 }

 

以上是关于[BZOJ5289][HNOI2018]排列(拓扑排序+pb_ds)的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj5289][Hnoi2018]排列——贪心+堆

[BZOJ5288][HNOI2018]游戏(拓扑排序)

bzoj5288 [Hnoi2018]游戏

拓扑排序BZOJ4010-[HNOI2015]菜肴制作

BZOJ4010[HNOI2015]菜肴制作 拓扑排序

BZOJ4010 HNOI2015 菜肴制作 拓扑排序+贪心