• 抓捕盗窃犯


    题目链接:https://ac.nowcoder.com/acm/contest/373/C

    链接:https://ac.nowcoder.com/acm/contest/373/C
    来源:牛客网

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    Q市发生了一起特大盗窃案。这起盗窃案是由多名盗窃犯联合实施的,你要做的就是尽可能多的抓捕盗窃犯。
    已知盗窃犯分布于 N N个地点,以及第 i i个地点初始有 ai ai名盗窃犯。
    特别的是,对于每一个地点 u u,都有一个固定的地点 v v--当前如果某个盗窃犯位于地点 u u,在下一个时刻他会移动到地点 v v。
    你需要通过初始时在某些点设置哨卡来捉住他们。
    现在你可以在 M M个地点设置哨卡,如果在某个地点设置哨卡,你可以抓获在任一时刻经过该地点的盗窃犯。
    也就是说,哨卡存在的时间是无限长,但哨卡不能移动。

    输入描述:

    第一行两个整数 N,M(1N,M105) N,M(1≤N,M≤105)。
    第二行 N N个整数 a1a2...aN a1a2...aN (0a1,a2,...aN105) (0≤a1,a2,...aN≤105),表示第 i i个地点初始有 ai ai名盗窃犯。
    第三行 N N个整数 v1v2...vN v1v2...vN (1v1,v2,...vNN) (1≤v1,v2,...vN≤N),表示当前处于地点 i i的盗窃犯下一个时刻会移动到地点 vi vi。

    输出描述:

    输出一行一个整数--能够抓捕到的最大数量。
    示例1

    输入

    复制
    8 2
    1 2 3 4 1 2 3 12
    2 3 3 3 6 7 5 8

    输出

    复制
    22

    说明

    对于样例一,一种可行的方案是:

    在地点3、地点8分别设置一个哨卡,此时答案为1+2+3+4+12=22
    示例2

    输入

    复制
    8 2
    1 2 3 4 5 6 7 8
    2 3 4 5 6 7 8 8

    输出

    复制
    36

    说明

    对于样例二,一种可行的方案是:

    在地点2、地点8分别设置一个哨卡,此时答案为1+2+3+4+5+6+7+8=36

    思路:就是并查集,自己也不是没学过并查集,但是却没想到这题是并查集来写,其中有一些处理很好,以前从来没看过这样处理的,先把属于一个块的分好,再遍历一遍N,这时把每个块的总和加到
    根节点上,最后把这个总和存入容器中,排个序就是答案了。。。 自己真的很菜
    看代码:
    #include<iostream>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int maxn=1e5+50;
    LL fa[maxn],sum[maxn];
    LL a[maxn];
    LL N,M;
    bool cmp(const LL x,const LL y)
    {
        return x>y;
    }
    void Init()
    {
        memset(sum,0,sizeof(sum));
        for(LL i=1;i<=N;i++) fa[i]=i;
        return ;
    }
    LL Find(LL x)
    {
        //cout<<"***"<<x<<endl;
        if(fa[x]==x) return fa[x];
        return fa[x]=Find(fa[x]);
    }
    void Union(LL x,LL y)
    {
        LL fx=Find(x);
        LL fy=Find(y);
        if(fx!=fy) fa[fx]=fy;
        return ;
    }
    int main()
    {
        vector<LL> ans;
        ans.clear();
        scanf("%lld%lld",&N,&M);
        Init();
        for(LL i=1;i<=N;i++)
        {
            scanf("%lld",&a[i]);
        }
        for(LL i=1;i<=N;i++)
        {
            LL x;
            scanf("%lld",&x);
            Union(i,x);
        }
        //cout<<"**"<<endl;
        for(LL i=1;i<=N;i++)
        {
            LL x=Find(i);
            sum[x]+=a[i];
        }
        //cout<<"*"<<endl;
        for(LL i=1;i<=N;i++)
        {
            if(fa[i]==i) ans.push_back(sum[i]);
        }
        sort(ans.begin(),ans.end(),cmp);
        //for(int i=0;i<ans.size();i++) cout<<ans[i]<<" ";
        //cout<<endl;
        LL asum=0;
        LL len=ans.size();
        for(LL i=0;i<min(M,len);i++) asum+=ans[i];
        printf("%lld
    ",asum);
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    随机数 | @counter-style.range (Counter Styles)
    长度 | <length> (Values & Units)
    重复线性渐变 | repeating-linear-gradient (Image Values)
    重复径向渐变 | repeating-radial-gradient() (Image Values)
    重复 | repeat (Grid Layout)
    逻辑属性 | CSS Logical Properties (Logical Properties)
    通用选择器 | Universal selectors (Selectors)
    ProxySQL Admin管理接口
    《【Graph Embedding】LINE:算法原理,实现和应用》
    《AutoInt:基于Multi-Head Self-Attention构造高阶特征》
  • 原文地址:https://www.cnblogs.com/caijiaming/p/10478680.html
Copyright © 2020-2023  润新知