POJ 3270

省赛被虐了,最近就搞搞数论和组合数学的题目。

这题主要运用了组合数学中的置换群概念,其他也没什么好说的了。

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<queue>

 4 #include<vector>

 5 #include<algorithm>

 6 #define MAXN 10005

 7 using namespace std;

 8 int data[MAXN],note[MAXN];

 9 bool vis[MAXN];

10 

11 int search(int n, int x)

12 {

13   int l(1),r(n);

14   int mid = (l + r)/2;

15   while (l <= r) {

16     if (note[mid] == x)return mid;

17     if (note[mid] < x)l = mid + 1;

18     if (note[mid] > x)r = mid - 1;

19     mid = (l + r)/2;  

20   }  

21   return 0;

22 }

23 

24 void ini(int n)

25 {

26   memset(vis,false,sizeof(vis));

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

28     scanf("%d",&data[i]);

29     note[i] = data[i];  

30   }

31   sort(note+1,note+n+1);

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

33     data[i] = search(n+1,data[i]);    

34   }     

35 }

36 

37 int main()

38 {

39   int n;

40   scanf("%d",&n);

41   ini(n);

42   priority_queue<int, vector<int>, greater<int> > Q;

43   int sum1(0), sum2(0), ans = 0;

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

45     if (!vis[i]) {

46       sum1 = sum2 = 0;

47       vis[i] = true;

48       Q.push(i);

49       int temp = i;

50       sum1 += 2*note[i] + 2*note[1];

51       while (!vis[data[temp]]) {

52         temp = data[temp];

53         vis[temp] = true;

54         sum1 += note[temp] + note[1];

55         Q.push(temp);  

56       }

57       if (Q.size() == 1) {

58         Q.pop();

59         continue;

60       }

61       int x = Q.top();//cout<<x<<" ";

62       Q.pop();

63       while (!Q.empty()) {

64         //cout<<Q.top()<<" ";

65         sum2 += note[x] + note[Q.top()];

66         Q.pop();  

67       }

68       //cout<<sum1<<" "<<sum2<<endl;

69       ans += min(sum1,sum2);  

70     }    

71   }

72   cout<<ans<<endl;

73   system("pause");

74   return 0;  

75 }

你可能感兴趣的:(poj)