1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "cmath" #include "vector" #include "map" #include "set" #include "queue" using namespace std; #define MAXN 500006
#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i) #define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define vi vector<int> #define all(x) (x).begin() , (x).end() #define mem( a ) memset( a , 0 , sizeof a ) typedef long long ll; #define P 1000000007 int n , k; int f[MAXN] , w[MAXN] , cnt; struct node { ll w; int m , idx; ll as; int tim = 0; node( ll w = 0 , int m = 0 , int idx = 0 , ll as = 0 , int tm = 0 ) : w(w) , m(m) , idx(idx) , as(as) , tim(tm) {} bool operator < ( node x ) const { return 1ll * w * x.m > 1ll * x.w * m; } node operator + ( node x ) { return node( x.w + w , m + x.m , idx , as + x.as + x.w * 1ll * m , ++ cnt ); } } nd[MAXN] ; priority_queue<node> Q;
int fa[MAXN]; int find( int x ) { return x == fa[x] ? x : fa[x] = find( fa[x] ); }
void solve( ) { cin >> n; rep( i , 1 , n ) fa[i] = i; rep( i , 1 , n ) { scanf("%d",&f[i]); if( find( i ) == find( f[i] ) ) puts("-1") , exit(0); else { fa[find( i )] = find( f[i] ); } } rep( i , 1 , n ) fa[i] = i; rep( i , 1 , n ) { scanf("%d",w + i); Q.push( nd[i] = (node) { w[i] , 1 , i , w[i] , 0 } ); } while( !Q.empty() ) { node tp = Q.top(); Q.pop(); if( nd[tp.idx].tim != tp.tim ) continue; int x = find( f[tp.idx] ); fa[tp.idx] = x; nd[x] = nd[x] + tp; if( x ) Q.push( nd[x] ); } printf("%lld\n",nd[0].as); }
signed main() {
solve(); }
|