hdu 5495 LCS(并查集)

Problem Description
You are given two sequence {a1,a2,...,an} and {b1,b2,...,bn}. Both sequences are permutation of {1,2,...,n}. You are going to find another permutation {p1,p2,...,pn} such that the length of LCS (longest common subsequence) of {ap1,ap2,...,apn} and {bp1,bp2,...,bpn} is maximum. 
 
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n(1n105) - the length of the permutation. The second line contains n integers a1,a2,...,an. The third line contains n integers b1,b2,...,bn.

The sum of n in the test cases will not exceed 2×106.
 
Output
For each test case, output the maximum length of LCS.
 
题意:给你两串数字然后让你求一个顺序使得这两个序列按这种顺序排列后LCS最大,并输出LCS的长度。
 
由于这题的数据大用LCS肯定不行,枚举方案肯定也不行。但是由于可以随意移动且数字是1~n中的所有数,所以可以将关联的数字求出来,
这些关联的数最大能组成len-2的LCS序列拿例题打个比方。
6
1 5 3 2 6 4
3 6 2 4 5 1
关联后可以得到
(1-3-2-4-1),(5-6-5)
1 3 2 4       5 6
3 2 4 1       6 5
所以组合后LCS就为(5-2)+(3-2)=4
还有如果只有两个如(5-5)这时候加1就行
 
 
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int M = 1e5 + 10;
int a[M] , b[M];
int f[M] , va[M];
void init(int n) {
    for(int i = 0 ; i <= n ; i++) {
        f[i] = i;
        va[i] = 1;
    }
}
int find(int x) {
    if(x != f[x])
        f[x] = find(f[x]);
    return f[x];
}
void Union(int x , int y) {
    int xx = find(x);
    int yy = find(y);
    if(xx != yy) {
        f[x] = yy;
        va[yy] += va[xx];
    }
}
int main()
{
    int t;
    scanf("%d" , &t);
    while(t--) {
        int n;
        scanf("%d" , &n);
        init(M);
        for(int i = 0 ; i < n ; i++) {
            scanf("%d" , &a[i]);
        }
        for(int i = 0 ; i < n ; i++) {
            scanf("%d" , &b[i]);
            Union(a[i] , b[i]);
        }
        int count = 0;
        for(int i = 0 ; i < n ; i++) {
            if(f[a[i]] == a[i]) {
                if(va[a[i]] == 1) {
                    count++;
                }
                else {
                    count += (va[a[i]] - 1);
                }
            }
        }
        printf("%d
" , count);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/TnT2333333/p/6053923.html