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 }