交换瓶子(图论 贪心)

1224. 交换瓶子 - AcWing题库

把每一个瓶子看成一个点,从每个瓶子向他应该在的那个位置的瓶子连一条边

通过这个方式,我们就可以连出n条边

观察可以发现这些图有特点:

n个点 连成n条边

因为每个点会指向它应该在的位置的那个点,他所在位置的对应的点会指向他,所以每个点的出度和入度都为1

不会有以下情况

都会是一个一个环

最终希望完成的样子是一个升序的 ,把整个图都变成自环

对点进行操作,分两种情况:

1️⃣交换同一个环内的点

如图,交换1 和 3的位置,意味着改变点1和点2的出边,让点1的出边指向点2先前出边方向,点2指向点1 先前出边的方向

可以发现将一个环裂开成了两个环

2️⃣交换不同环中的点

可以发现合并了两个环

初始的时候我们假设有k个环,n个点,我们的目标是将所有的环拆解成自环,每次操作最多增加一个环,因此次数 >= n-k次,只要有一个环里面存在两个或以上的点,我们就必然可以把它分裂一下,变成两个环,所以必然存在一种方案,可以使我们恰好操作n-k次就可以把k个环分解成n个环

所以答案>=n-k 且可以取到n-k

cpp 复制代码
#include <iostream>

using namespace std;

const int N = 1e4 + 10;

int n;
int b[N];
bool st[N];

int main() {
    cin >> n;
    
    for (int i = 1;i <= n;i++) {
        cin >> b[i];
    }
    
    int cnt = 0;
    for (int i = 1;i <= n;i++) {
        if (!st[i]) {
            cnt++;
            for (int j = i;!st[j];j=b[j]) {
                st[j] = true;
            }
        }
    }
    
    int res = n - cnt;
   
    cout << res << endl;
    
    return 0;
}
相关推荐
IT猿手4 分钟前
超多目标优化:基于导航变量的多目标粒子群优化算法(NMOPSO)的无人机三维路径规划,MATLAB代码
人工智能·算法·机器学习·matlab·无人机
Erik_LinX14 分钟前
算法日记25:01背包(DFS->记忆化搜索->倒叙DP->顺序DP->空间优化)
算法·深度优先
Alidme21 分钟前
cs106x-lecture14(Autumn 2017)-SPL实现
c++·学习·算法·codestepbystep·cs106x
小王努力学编程22 分钟前
【算法与数据结构】单调队列
数据结构·c++·学习·算法·leetcode
最遥远的瞬间24 分钟前
15-贪心算法
算法·贪心算法
维齐洛波奇特利(male)1 小时前
(动态规划 完全背包 **)leetcode279完全平方数
算法·动态规划
项目申报小狂人2 小时前
改进收敛因子和比例权重的灰狼优化算法【期刊论文完美复现】(Matlab代码实现)
开发语言·算法·matlab
让我们一起加油好吗3 小时前
【排序算法】六大比较类排序算法——插入排序、选择排序、冒泡排序、希尔排序、快速排序、归并排序【详解】
c语言·算法·排序算法
夏末秋也凉3 小时前
力扣-贪心-53 最大子数组和
数据结构·算法·leetcode
liruiqiang054 小时前
机器学习 - 投票感知器
人工智能·算法·机器学习