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 }
posted on 2012-05-23 13:17  Dev-T  阅读(252)  评论(0编辑  收藏  举报