b_mt_成为漂亮序列的操作次数(建图+统计连通块个数)

有一个长度为n (n为偶数)的序列A,序列中的数都是介于[1,100000的整数。
我想把这个序列变得漂亮后再送回给你。
你觉得一个序列是漂亮的当且仅当这个序列的前一半和后 一半是一样的,即对于1< =i< =n/2都满足A[i1= A[i+n/2]。

我可以按进行以下操作任意次:选择两个介于[1,100000]之间的数x和y,然后将序列A中所有值为x的数替换为y。
我想知道他最少需要操作多少次可以把序列变成漂亮的。

输入描述
第一行是一个整数n,表示序列的长度。数据保证n为偶数。
第二行有n个用空格隔开的整数,第i个数表示A[的值。数据保证1< =A[<=100000。
输出描述
输出我需要的最少操作次数。
输入
10
4 2 1 5 2 10 2 1 5 8
输出:2

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 +5;
vector<int> g[N];
int vis[N];

void dfs(int u) {
    vis[u] = 1;
    for (int v : g[u]) {
        if (!vis[v]) {
            dfs(v);
        }
    }
}
void f3() {
    int n;
    cin >> n;
    vector<int> a(n);
    unordered_set<int> nums;
    for (int i = 0; i < n; i++)  {
        cin >> a[i];
    }

    for (int i = 0; i < n/2; i++) {
        if (a[i] != a[i + n / 2]) {
            g[a[i]].push_back(a[i + n / 2]);
            g[a[i + n / 2]].push_back(a[i]);
            nums.insert(a[i]);
            nums.insert(a[i + n / 2]);
        }
    }
    int ltk = 0;
    for (int t : nums) {
        if (!vis[t]) {
            dfs(t);
            ltk++;
        }
    }
    cout << nums.size() - ltk << '\n';
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    f3();
    return 0;
}
posted @ 2021-08-08 14:46  童年の波鞋  阅读(96)  评论(0编辑  收藏  举报