POJ3270.Cow Sorting

Posted sigongzi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3270.Cow Sorting相关的知识,希望对你有一定的参考价值。

题解

用到一点群论的知识!
我们发现把操作写成一个置换后,一定是单个置换圈的内进行操作,把置换圈进行扩大的操作不优
我们有两个办法,一个是用全局最小的换进来,代替这个圈里最小的值,交换操作完成后再换出去,二是用圈里最小的换完一圈
就两个操作,计算后贪心即可

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <cstring>
#include <ctime>
#include <map>
#include <algorithm>
#include <cmath>
#define MAXN 100005
#define eps 1e-8
//#define ivorysi
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long int64;
typedef double db;

int N;
int a[MAXN],ra[MAXN],pos[MAXN],num[MAXN],line[MAXN],cnt;
bool vis[MAXN];
int64 ans = 0;
void dfs(int u) {
    if(vis[u]) return;
    line[++cnt] = u;
    vis[u] = 1;
    dfs(pos[num[u]]);
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    scanf("%d",&N);
    for(int i = 1 ; i <= N ; ++i) {scanf("%d",&a[i]);pos[a[i]] = i;num[i] = a[i];}
    sort(num + 1,num + N + 1);
    for(int i = 1 ; i <= N ; ++i) ra[num[i]] = i;
    cnt = 0;
    dfs(pos[num[1]]);
    for(int i = 1 ; i <= cnt ; ++i) {
        if(line[i] != pos[num[1]]) ans += num[1] + a[line[i]]; 
    }
    for(int i = 1 ; i <= N ; ++i) {
        if(!vis[i]) {
            cnt = 0;dfs(i);
            int minn = i;
            for(int j = 1 ; j <= cnt ; ++j) {
                if(a[line[j]] < a[minn]) minn = line[j];
            }
            int64 tmp1 = 0,tmp2 = 0;
            for(int j = 1 ; j <= cnt ; ++j) {
                if(line[j] != minn) tmp1 += a[minn] + a[line[j]];
            }
            for(int j = 1 ; j <= cnt ; ++j) {
                tmp2 += num[1] + a[line[j]];
            }
            tmp2 += num[1] + a[minn];
            ans += min(tmp1,tmp2);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

以上是关于POJ3270.Cow Sorting的主要内容,如果未能解决你的问题,请参考以下文章

poj 3270 Cow Sorting

POJ 3270. Cow Sorting & 51nod 1125 交换机器的最小代价

[POJ1007]DNA Sorting

POJ 1007 DNA Sorting

poj 1486 Sorting Slides

poj 1007 DNA Sorting