【题解】LuoGu3482:[POI2009]SLO-Elephants

Portal original title
first affirmed looking ring, the end of the enumeration, looking forward, because this is only one way to ensure that before
the ring to find out, take a look at how to calculate the cost of
a ring set up to find the sum of the sum sums u m , the number of elements in the ringlen lenl e n , the smallest elementin theringM in MinM i n , the smallest element in the entire inputminw minwm i n w

  • len = 1 len = 1 l e n=1. The entire ring is just one element, pointing to yourself, and nothing is required
  • len - 2 len-2 l e n2. Two elements point to each other, just exchange it, the cost issum sumsum
  • l e n > 2 len>2 l e n>2. Simulate it on the draft paper and find that it can be understood that each element is exchanged once to its target position, and there is an element on the way as a transit to help anotherlen − 1 len-1l e nOne element exchange, and at the same time exchange yourself. The element is naturally the smallest, namelyM in MinM i n , its degree, totallen − 1 len-1l e nOnce , it can also be understood that when all elements are exchanged once, it exchanges morelen − 2 len-2l e n2 times. So the cost issum + (len − 2) M in sum+(len-2)Minsum+( l e n2 ) M i n
    But there is another solution, we can take an element outside the ring as a transit, so the outsider must meet the minimum input, namelyminw minwm i n w , and then calculate the cost. I won’t repeat it here. It issum + Min + (len + 1) minw sum+Min+(len+1)minwsum+M i n+( l e n+1 ) m i n w

Code:

#include <bits/stdc++.h>
#define maxn 1000010
#define LL long long
using namespace std;
LL w[maxn], ans, sum, len, Min, minw;
int a[maxn], b[maxn], pre[maxn], vis[maxn], n;

inline int read(){
    
    
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
	return s * w;
}

void dfs(int u){
    
    
	vis[u] = 1, sum += w[a[u]], ++len, Min = min(Min, w[a[u]]);
	if (!vis[pre[b[u]]]) dfs(pre[b[u]]);
}

int main(){
    
    
	n = read();
	minw = 1e9;
	for (int i = 1; i <= n; ++i) minw = min(minw, w[i] = read());
	for (int i = 1; i <= n; ++i) pre[a[i] = read()] = i;
	for (int i = 1; i <= n; ++i) b[i] = read();
	for (int i = 1; i <= n; ++i)
		if (!vis[i]){
    
    
			sum = 0, len = 0, Min = 1e9;
			dfs(i);
			if (len == 1);
			else if (len == 2) ans += sum;
			else ans += sum + min((len - 2) * Min, (len + 1) * minw + Min);
		}
	printf("%lld\n", ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/ModestCoder_/article/details/108555269