C. Bertown Subway

题目解析

通过分析题目得到,车站之间回形成环。题目要求的是通过改变两个数p[i],使得车站到其他车站的可达数量最大化(便利最大化)。因为每一个i对应的pi值都是不同的,所以只能通过交换两个数来实现。

将车站到车站之间的路径可以构成环,环中的每个车站都可以到达其他的车站,若环的长度是a,则车站可达的数量为a的2次方

题目要求可达的数量最大化,则只需要让两个长度最大的环连接到一起即可。若这两个环的长度分别为a和b,则两个连接在一起形成的大环的可达数量(便利度)为(a + b)^ 2。

利用上述思路编写的代码如下:

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define MAXN 100000 + 5
#define ll long long

int p[MAXN];//存储站信息
bool visited[MAXN];//用于判断当前站是否被访问了,避免重复访问环
int main()
{
    vector<ll> v;//存储所有环的长度
    int n;
    ll r = 0;//结果

    cin >> n;
    for(int i = 1; i <= n; i++)cin >> p[i];

    for(int i = 1; i <= n; i++)//i表示的是本站
    {
        if(visited[i] == true)continue;

        //利用后续的代码求环的长度,这一部分是最重要的
        ll cnt = 1;
        int x = p[i];//x是本站的目的站
        visited[x] = true;
        while(x != i)//如果说没有形成环继续执行
        {
            x = p[x];
            visited[x] = true;
            cnt++;//这个cnt是环的长度
        }

        v.push_back(cnt);//将这个环的长度放进数组中
    }
    sort(v.begin(), v.end());//从小到大进行排序
    if(v.size() >= 2)//其中有大于等于2的环数
    {
        r = v[v.size() - 2] + v[v.size() - 1];
        //现在r的值是最大的两个环长度之和
        r = r * r;//现在r的值是将两个环组合在一起的数对总和
        //(从一个站到另一个站的所有方式之和)
        for(int i = 0; i < v.size() - 2; i++)
        {
            r += v[i] * v[i];
        }
    }else//只有一个环,直接是长度的平方
    {
        r = v[0] * v[0];
    }
    cout << r;
    return 0;
}
相关推荐
大千AI助手28 分钟前
二元锦标赛:进化算法中的选择机制及其应用
人工智能·算法·优化·进化算法·二元锦标赛·选择机制·适应生存
独自破碎E31 分钟前
归并排序的递归和非递归实现
java·算法·排序算法
K 旺仔小馒头1 小时前
《牛刀小试!C++ string类核心接口实战编程题集》
c++·算法
草莓熊Lotso2 小时前
《吃透 C++ vector:从基础使用到核心接口实战指南》
开发语言·c++·算法
2401_841495649 小时前
【数据结构】红黑树的基本操作
java·数据结构·c++·python·算法·红黑树·二叉搜索树
西猫雷婶9 小时前
random.shuffle()函数随机打乱数据
开发语言·pytorch·python·学习·算法·线性回归·numpy
小李独爱秋10 小时前
机器学习中的聚类理论与K-means算法详解
人工智能·算法·机器学习·支持向量机·kmeans·聚类
小欣加油12 小时前
leetcode 1863 找出所有子集的异或总和再求和
c++·算法·leetcode·职场和发展·深度优先
十八岁讨厌编程12 小时前
【算法训练营Day27】动态规划part3
算法·动态规划
炬火初现13 小时前
Hot100-哈希,双指针
算法·哈希算法·散列表