! AHOI / HNOI2018 arrangement



The first \ (I \) number to be placed in the first \ (a_i \) back number

There is no solution ring

Original ideas:

Even edge, topological sorting, but each time bomb pop \ (w_i \) maximum

But this is the wrong idea of ​​greed, because the smaller the back may have been a large number of

SOL:

Or even the edge found in the formation of a tree rooted 0

The current minimum weight point \ (i \)

  1. If there is no father \ (a_i = 0 \) , then direct elections
  2. If the father, the father must be selected immediately choose this point, so the merger \ (i \) with his father

After several merger each point of a sequence, then how do minimum sentence Who /

\ (a, b \) has the sequence relationship

\(W_{ab}=\sum_{i=1}^{sz_a}w_{a_i}+\sum_{i=1}^{sz_b}(i+sz_a)w_{b_i}\)

\(W_{ba}=\sum_{i=1}^{sz_b}w_{b_i}+\sum_{i=1}^{sz_a}(i+sz_b)w_{a_i}\)

\ (W_ {ab} {-W_} = ba-sz_aW_b sz_bW_a \)

\(W_{ab}>W_{ba}\to\frac{W_a}{sz_a}<\frac{W_b}{sz_b}\)

Small average value may be superior in front of the discharge

With \ (set \) to find the minimum point, the merger with disjoint-set, and count the contribution

Time complexity \ (O (nlog_n) \)

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return f==1?x:-x;
}
const int N=5e5+4;
int n,fa[N],a[N],w[N],sz[N],ans;
int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
struct cmp{
	bool operator()(int x,int y){
		return sz[x]*w[y]==w[x]*sz[y]?x<y:sz[x]*w[y]>w[x]*sz[y];
	}//平均小的放前面更优 
};
set<int,cmp>s;
signed main(){
	n=read();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=n;i++){
		w[i]=read();
		sz[i]=1;
		s.insert(i);
		fa[i]=i;
	}
	sz[0]=1;//!以0为根的树 
	for(int i=1;i<=n;i++){
		int x=*s.begin(),fx=find(a[find(x)]);
		if(find(x)==fx){puts("-1");return (0-0);}
		s.erase(s.begin());
		if(fx)s.erase(fx);
		ans+=sz[fx]*w[x];
		sz[fx]+=sz[x];
		w[fx]+=w[x];
		fa[x]=fx;
		if(fx)s.insert(fx);
	}
	cout<<ans;
	return (0-0);
}

Guess you like

Origin www.cnblogs.com/aurora2004/p/12582425.html