• 大地的复苏


    大地的复苏

     时间限制: 1 s
     空间限制: 64000 KB
    题目描述 Description

      萌萌哒tangjz感应到OI村遭到了坏人Kinger Tangent的侵袭,急急忙忙的又赶了回来。 T_T

      目前局势非常不好,Kinger Tangent正在施法引出岩浆不便移动,所以tangjz准备在一些地方布下防御塔。

      现在的OI村有N个高地,编号分别为1~N。

      萌萌哒tangjz布下的神の防御塔有着正义力量的加成,除了保护该地点外,还强制额外庇护另外一个地点,不过如果额外能庇护的地点已经受到保护了,就不能再该地点布置防御塔,否则会由于能量过大造成毁灭(不论主动被动,每个地点只能被庇护一次)。 >_<

    输入描述 Input Description

      第一行一个正整数N,表示OI村高地个数。

      第二行有N个正整数,第i个正整数表示在第i个高地建立防御塔可以额外庇护的地点。

    输出描述 Output Description

      最多可以建的防御塔个数。

    样例输入 Sample Input

    10
    4 5 5 2 3 7 8 9 10 9

    样例输出 Sample Output

    4

    数据范围及提示 Data Size & Hint

    对于30%的数据:
    对于60%的数据:
    对于100%的数据:每个地点都可以庇护一个其他的地点

    题目链接:http://codevs.cn/problem/2820/


    拓扑排序+贪心。瞎搞了好久的动态规划。。。。。首先分析偶数链在环上的情况,如果贪心的选择链尾的最后一个点,发现选择到最后不会影响环上的点,如果是奇数链在环上,则最后一个选择的点一定会影响到环上的点,因此我们此时要对环进行继续贪心。如果在对环进行贪心的时候发现环上某个点还连着某一条链,如果是偶数链则没有影响,如果是奇数链,发现我们要是选了这个点,环上贡献加一,但是链上贡献减一,如果不选这个点,环上贡献减一,链上贡献加一,因此表面上看选不选这个点对答案没有影响,其实不然,如果选了这个点,环上这个点的下一个点就不能选了,如果不选这个点,这个点的下一个点还可以选。因此贪心的考虑我们不能选这个点。以上操作可以通过拓扑排序完美完成。

    #include<bits/stdc++.h>
    #define N 2000000
    int next[N],ind[N],vis[N],q[N];
    int main()
    {
        int n,i,ans=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&next[i]);
            ind[next[i]]++;
        }
        int x,tot=0;
        for(i=1;i<=n;i++)
         if(ind[i]==0)q[++tot]=i;
    
        while(tot)
        {
            int now=q[tot--],nex=next[now];
            vis[now]=true;
            if(!vis[nex])
            {
                vis[nex]=true;
                ans++;
                if(!vis[next[nex]]&&(--ind[next[nex]]==0))
                q[++tot]=next[nex];
            }
        }
    
        for(i=1;i<=n;i++)
        if(!vis[i])
         {
             int now=i,nex=i,c=1;
             vis[i]=true;
             while(1)
             {
                 nex=next[nex];
                 if(nex==now)
                 {
                     ans+=c/2;
                     break;
                 }
                 else
                 {
                     c++;
                     vis[nex]=true;
                 }
             }
         }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    linux 6 安装 Nagios服务
    linux 6 安装 Nginx服务
    Rsync的配置与使用
    linux 6 搭建 msyql 服务
    linux6搭建Apache服务
    Linux 7搭建NFS服务
    Linux 6 忘记root密码重置
    简单makefile
    多线程c++11编程题目
    redis 代码结构与阅读顺序
  • 原文地址:https://www.cnblogs.com/tian-luo/p/9746162.html
Copyright © 2020-2023  润新知