1. 程式人生 > >CodeForces - 441D: Valera and Swaps(置換群)

CodeForces - 441D: Valera and Swaps(置換群)

numbers contain ron namespace opera 一個 pac element line

A permutation p of length n is a sequence of distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n). A permutation is an identity permutation, if for any i the following equation holds pi = i.

A swap (i, j) is the operation that swaps elements p

i and pj in the permutation. Let‘s assume that f(p) is the minimum number of swaps that you need to make the permutation p an identity permutation.

Valera wonders, how he can transform permutation p into any permutation q, such that f(q) = m, using the minimum number of swaps. Help him do that.


Input

The first line contains integer n (1 ≤ n ≤ 3000) — the length of permutation p. The second line contains n distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n) — Valera‘s initial permutation. The last line contains integer m

(0 ≤ m < n).

Output

In the first line, print integer k — the minimum number of swaps.

In the second line, print 2k integers x1, x2, ..., x2k — the description of the swap sequence. The printed numbers show that you need to consecutively make swaps (x1, x2), (x3, x4), ..., (x2k - 1, x2k).

If there are multiple sequence swaps of the minimum length, print the lexicographically minimum one.

Examples Input
5
1 2 3 4 5
2
Output
2
1 2 1 3
Input
5
2 1 4 5 3
2
Output
1
1 2
Note

Sequence x1, x2, ..., xs is lexicographically smaller than sequence y1, y2, ..., ys, if there is such integer r (1 ≤ r ≤ s), that x1 = y1, x2 = y2, ..., xr - 1 = yr - 1 and xr < yr.

題意:有函數f(p),表示把排列p,變為順序的排列,所用的最小交換次數,這裏的交換是兩兩交換,而不是相鄰交換。

現在給你排列p和m,讓你交換最小的次數,使得排列變為q,滿足f(q)=m,如果有多種交換方案,輸出字典序最小的;

思路:1,把排列p變為1,2,3....p,的最小次數=N-環數。假如N-環數<m,那就加環。 否則減環。

2,如果交換兩個不在同一個環的位置的數,那麽環數+1;

3,如果交換在同一個環的位置的數,那麽環數-1;

所以我們的任務就是加環或者減環,而每次分組的復雜度是O(N);我們最多加N次環,所以我們可以暴力交換,交換後重新分組。

復雜度O(N^2);

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=3010;
int a[maxn],vis[maxn],tot,N,M;
void dfs(int u)
{
    if(vis[u]) return ;
    vis[u]=tot;
    dfs(a[u]);
}
void rebuild()
{
    tot=0; rep(i,1,N) vis[i]=0;
    rep(i,1,N) if(!vis[i]) tot++,dfs(i);
}
int main()
{
    scanf("%d",&N);
    rep(i,1,N) scanf("%d",&a[i]);
    rebuild();
    scanf("%d",&M);
    if(M==N-tot) return puts("0"),0;
    int ans,opt=0;
    if(M>N-tot) ans=M-N+tot,opt=1; //
    else ans=N-tot-M;//
    printf("%d\n",ans);
    rep(i,1,N)
     rep(j,1,N){
        if(!ans) break;
        if(i!=j&&(abs(vis[i]-vis[j])?1:0)==opt) {
            swap(a[i],a[j]); ans--;
            printf("%d %d ",i,j);
            rebuild();
        }
    }
    return 0;
}

CodeForces - 441D: Valera and Swaps(置換群)