Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 6364 | Accepted: 2462 |
Description
Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cows are more likely to damage FJ's milking equipment, FJ would like to reorder the cows in line so they are lined up in increasing order of grumpiness. During this process, the places of any two cows (not necessarily adjacent) can be interchanged. Since grumpy cows are harder to move, it takes FJ a total of X+Y units of time to exchange two cows whose grumpiness levels are X and Y.
Please help FJ calculate the minimal time required to reorder the cows.
Input
Output
Sample Input
3 2 3 1
Sample Output
7
Hint
#include <cstdio> #include <cstring> #include <algorithm> #define LL long long #define MAX 10000+10 #define INF 1000000000+10 using namespace std; struct record { int val, pos;//分别表示 数值和这个数有哪个位置的数置换得到的 }num[MAX]; bool cmp(record a, record b) { return a.val < b.val;//按照数值升序排列 } int a[MAX];//n个数 int vis[MAX];//标记当前元素在不在某一个子群里面 int main() { int n, i, j; LL ans;//最小 花费 int Minn;//记录数列里面最小值 int sonMin;//记录当前子群的最小值 int t;//记录子群元素个数 while(scanf("%d", &n) != EOF) { Minn = INF; ans = 0; for(i = 1; i <= n; i++) { scanf("%d", &a[i]); ans += a[i]; num[i].val = a[i]; num[i].pos = i; Minn = min(Minn, a[i]);//记录数列里面最小的值 } sort(num+1, num+n+1, cmp);//升序排列 memset(vis, 0, sizeof(vis));//初始化 for(i = 1; i <= n; i++) { j = i; if(!vis[j])//不存于 当前所有置换子群中 { t = 0; sonMin = a[j]; while(!vis[j]) { vis[j] = 1;//标记 t++;//元素个数加一 sonMin = min(sonMin, a[j]);//更新子群最小值 j = num[j].pos;//->变换到它的上一位置 } ans += min((t-2)*sonMin, (t+1)*Minn+sonMin); } } printf("%lld\n", ans); } return 0; }