poj 3270 Cow Sorting

http://poj.org/problem?id=3270

给n头牛 让你把他们升序排序 每次交换两个牛 交换花费是两个牛值之和

求最小花费

黑书上有 P248     求循环

每个循环进行判断  一个循环的花费有两种情况可能为最优

1 用循环内最小的花费牛 和其他牛 进行交换

2 或是用全局最小花费牛 先和本环内最小花费牛交换 然后一样  最后再交换回来就可以了

代码及其注释:

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<map>

#include<cmath>

#define LL long long



using namespace std;



const int N=10005;

struct node

{

    int I;

    int k;

}mem[N];

int MIN;

bool cmp(node x,node y)

{

    return x.k<y.k;

}

int polya(int n)

{

    bool had[N];

    memset(had,false,sizeof(had));

    int ans=0;

    for(int i=1;i<=n;++i)

    {

        if(!had[i])//每个环 判断

        {

            had[i]=true;

            int num=1;

            int sum=mem[i].k;

            int m=mem[i].k;

            int l=mem[i].I;

            while(l!=i)

            {

                had[l]=true;

                num++;

                sum+=mem[l].k;

                m=min(m,mem[l].k);

                l=mem[l].I;

            }

            ans=ans+min((sum-m+m*(num-1)),((sum-m+MIN)-MIN+MIN*(num-1)+2*(MIN+m)));//两种情况取最小

            //cout<<ans<<endl;

        }

    }

    return ans;

}

int main()

{

    int n;

    while(scanf("%d",&n)!=EOF)

    {

        MIN=N;

        for(int i=1;i<=n;++i)

        {

            mem[i].I=i;;//位置

            scanf("%d",&mem[i].k);//花费

            MIN=min(MIN,mem[i].k);//求全局最小花费

        }

        sort(mem+1,mem+n+1,cmp);//排序

        printf("%d\n",polya(n));

    }

    return 0;

}

  

你可能感兴趣的:(sort)