T1 特工szp

【问题描述】

Byteotian 中央情报局 (BIA) 雇佣了许多特工. 他们每个人的工作就是监视另一名特工.
Byteasar 国王需要进行一次秘密行动,所以他要挑选尽量多的信得过的特工. 但是这项任务是如此的机密以至于所有参加行动的特工都必须至少被另一名没有参加任务的特工所监视(就是说如果某个特工参加了行动,那么原先监视他的那些特工中至少要有一个没有参加进行动). 给出监视任务的详情,要求计算最多能有多少个特工参与其中.

【输入格式】

第一行只有一个整数, n – 特工的总数, 2 <= n <= 1000000. 特工从 1 到 n编号. 接下来 n 行每行一个整数 ak 表示特工 k 将要监视特工 ak , 1 <= k <= n, 1<= ak <= n, ak <> k.

【输出格式】

打印一个数,最多能有多少特工参加入这个任务.

【样例输入】

6
2
3
l
3
6
5

【样例输出】

3

Solution

来源:POI

①基环内向树+dp

每个点只有一条出边,基环内向树

将内向树先做了f[x][0]代表这个点不选,f[x][1]代表这个点选.转移(y为x的儿子):f[x][0]+=max(f[y][0],f[y][1]),f[i][1]=max(1+f[i][0]+f[y][0]-max(f[y][0],f[y][1]),f[i][1]);

做环的时候先随意选一个点(我选的第一个)割环为链,就是把第一个和最后一个点分开.

记g[x][0]为x选的个数,g[x][1]为x不选的个数

枚举最后一个点的情况(l为首个,r为末个),

0时,g[q[l]][0]=f[q[r]][1]+f[q[l]][0],g[q[l]][1]=f[q[r]][1]+f[q[l]][1];

1时,g[q[l]][0]=f[q[r]][0]+f[q[l]][0],g[q[l]][1]=f[q[r]][0]+max(f[q[l]][0]+1,f[q[l]][1]?f[q[l]][1]:1);

然后O(n)扫一遍环g[q[i]][0]=max(g[q[i-1]][0],g[q[i-1]][1])+f[q[i]][0],g[q[i]][1]=max(max(g[q[i-1]][0],g[q[i-1]][1])+f[q[i]][1],max(f[q[i]][0]+1,f[q[i]][1])+g[q[i-1]][0]);

注意特判当枚举最后一个点选的时候,如果!f[q[r]][1]即它没有子树(内向树),那么这次答案只能为g[q[r-1]][0]+1 else 每次答案max(g[q[r-1]][0],g[q[r-1]][1])

②贪心+拓扑序

又是鬼boy光勋考场上写的鬼算法

贪心思想,内向树中如果一个点它的儿子中有白点(不选),那么他肯定要选,因为他不选的话仅仅只会创造出一个黑点(它爸),而它爸还不如变白让爷爷变黑,对答案只增不少.

(题解)证明:若点i确定为白色,a[i]染白色也只能提供一个黑点,故a[i]染黑色不会差;若所有指向i的点均为黑色,则i只能是白色。

从度为零的点开始按拓扑序跑,将他爸标为黑点,爷爷度数--,度数为零入队.这样子连环也可以切开.然后还剩下一些单环(没有内向树),ans+=size/2.

Code

// <szp.cpp> - Thu Oct  6 08:17:54 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define MOD 1000000007
#define INF 1e9
#define IN inline
#define RG register
using namespace std;
typedef long long LL;
const int MAXN=1000010;
inline int max(int &x,int &y) {return x>y?x:y;}
inline int min(int &x,int &y) {return x<y?x:y;}
inline int gi() {register int w=0,q=0;register char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')q=1,ch=getchar();while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();return q?-w:w;
}
int t;bool u[MAXN],k[MAXN];int f[MAXN][2],g[MAXN][2];
int fr[MAXN],to[MAXN],fa[MAXN],ne[MAXN],q[MAXN];
IN void add(int u,int v){to[++t]=v;ne[t]=fr[u];fr[u]=t;
}
IN void dfs(int i){k[i]=1;for(int j=fr[i],y;y=to[j],j;j=ne[j])dfs(y),f[i][0]+=max(f[y][0],f[y][1]);for(int j=fr[i],y;y=to[j],j;j=ne[j])f[i][1]=max(1+f[i][0]+f[y][0]-max(f[y][0],f[y][1]),f[i][1]);
}
int work(int l,int r,bool ty){g[q[r-1]][0]=g[q[r-1]][1]=0;if(ty){g[q[l]][0]=f[q[r]][1]+f[q[l]][0];g[q[l]][1]=f[q[r]][1]+f[q[l]][1];}else{g[q[l]][0]=f[q[r]][0]+f[q[l]][0];g[q[l]][1]=f[q[r]][0]+max(f[q[l]][0]+1,f[q[l]][1]?f[q[l]][1]:1);}for(int i=l+1;i<r;i++){g[q[i]][0]=max(g[q[i-1]][0],g[q[i-1]][1])+f[q[i]][0];g[q[i]][1]=max(max(g[q[i-1]][0],g[q[i-1]][1])+f[q[i]][1],max(f[q[i]][0]+1,f[q[i]][1])+g[q[i-1]][0]);}if(ty&&!f[q[r]][1])return g[q[r-1]][0]+1;//this case=0return max(g[q[r-1]][0],g[q[r-1]][1]);
}
int main()
{freopen("szp.in","r",stdin);freopen("szp.out","w",stdout);int n=gi(),ans=0;for(int i=1;i<=n;i++){fa[i]=gi();add(fa[i],i);}while(1){int x,tot=0,o;for(x=1;x<=n;x++)if(!k[x])break;if(x==n+1)break;u[q[tot=1]=x]=1;while(!u[fa[x]])x=fa[x],u[q[++tot]=x]=1;x=fa[x];for(o=tot;o;o--)if(q[o]==x)break;for(int i=1;i<=tot;i++)u[q[i]]=0;q[o-1]=q[tot];for(int i=o;i<=tot;i++){k[q[i]]=1;for(int j=fr[q[i]],y;y=to[j],j;j=ne[j])if(y!=q[i-1])dfs(y),f[q[i]][0]+=max(f[y][0],f[y][1]);for(int j=fr[q[i]],y;y=to[j],j;j=ne[j])if(y!=q[i-1])f[q[i]][1]=max(1+f[q[i]][0]+f[y][0]-max(f[y][0],f[y][1]),f[q[i]][1]);}ans+=max(work(o,tot,1),work(o,tot,0));}printf("%d",ans);return 0;
}

View Code

②xyk's

// <szp.cpp> - Thu Oct  6 08:07:12 2016
// This file is created by XuYike's black technology automatically.
// Copyright (C) 2015 ChangJun High School, Inc.
// I don't know what this program is.

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long lol;
int gi(){int res=0,fh=1;char ch=getchar();while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();if(ch=='-')fh=-1,ch=getchar();while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();return fh*res;
}
const int MAXN=1000010;
const int INF=1e9;
int a[MAXN],d[MAXN];
bool vis[MAXN];
queue <int> q;
int main(){freopen("szp.in","r",stdin);freopen("szp.out","w",stdout);int n=gi();for(int i=1;i<=n;i++){a[i]=gi();d[a[i]]++;}for(int i=1;i<=n;i++)if(!d[i])q.push(i);int ans=0;while(!q.empty()){int x=q.front();q.pop();vis[x]=1;if(vis[a[x]])continue;vis[a[x]]=1;ans++;if(!--d[a[a[x]]])q.push(a[a[x]]);}for(int i=1;i<=n;i++){if(vis[i])continue;vis[i]=1;int sz=1;for(int j=a[i];j!=i;j=a[j]){vis[j]=1;sz++;}ans+=sz>>1;}printf("%d",ans);return 0;
}

View Code

转载于:https://www.cnblogs.com/YJinpeng/p/5935946.html

【POI】T1 特工 szp相关推荐

  1. Steam中国正式定名“蒸汽平台”

    Steam中国正式定名"蒸汽平台" 8月21日,Steam中国终于正式定名,新名叫做:"蒸汽平台".Steam中国(蒸汽平台)几乎完全独立于Steam,游戏库也 ...

  2. 模板 - DP动态规划

    整理的算法模板合集: ACM模板 目录 一:[背包] 二:[树形DP] 三:[数位DP] 四:[DP 的优化] 五:[插头 DP] 一:[背包] 1.[01背包] #include<algori ...

  3. WinDbg 脚本实例,可以显示 SSDT

    $$ ntcall Script v0.1 $$ by 小喂 2006.10.29 aS ufLinkS "<u><col fg=\\\"emphfg\\\&qu ...

  4. windbg 脚本学习总结

    windbg 脚本简单入门 http://blog.csdn.net/superliuxing/article/details/19206985 Windbg的功能自然不必说,集内核调试,应用程序调试 ...

  5. Windbg脚本和扩展工具开篇

    好长一段时间没写文章了,最近一直忙于为项目的可调式性做一些脚本和扩展工具,鉴于对windbg强大威力的震撼,以及相对较少的资料,笔者决定写一系列关于如何开发Windbg脚本和扩展命令的文章,您的支持是 ...

  6. windbg基本命令

    一. 1. !address eax 查看对应内存页的属性 2. vertarget 显示当前进程的大致信息 3 !peb 显示process Environment Block 4. lmvm 可以 ...

  7. windbg 常用命令详解

     一. 1. !address eax 查看对应内存页的属性 2. vertarget 显示当前进程的大致信息 3 !peb 显示process Environment Block 4. lmvm ...

  8. Windbg简明教程(转)

    Windbg是Microsoft公司免费调试器调试集合中的GUI的调试器,支持Source和Assembly两种模式的调试.Windbg不仅可以调试应用程序,还可以进行Kernel Debug(新版本 ...

  9. windbg调试驱动学习总结

    简单驱动编写与windbg调试 http://trustsec.blog.51cto.com/305338/64694/ 一.驱动编写 随着对windows系统的深入研究,越来越多的内核方面的知识被挖 ...

最新文章

  1. 治标不治本:POI Ptg错误的解决方法
  2. Javascript 用本页面文本域中的HTML代码打开一个空白窗口来运行
  3. SpringBootAdmin项目创建
  4. winform打开cad图纸_为什么CAD图纸打开后会显示很多问号“???”,该怎么解决...
  5. 【Linux】tail显示日志最后几行
  6. 【人工智能】给初学者们讲解人工神经网络(ANN)
  7. 使用 logback + slf4j 进行日志记录
  8. python的property用法_Python的@property使用方法详解
  9. zen-Coding
  10. 楼板计算塑形弹性_阶梯教室板模板支架工程方案计算书(仅供参考)
  11. Windows下安装pip
  12. 融创孙宏斌:我们现在是安全第一|一点财经
  13. JavaScript中onload和unload用法
  14. PMI、国家外专局-项目管理高端论坛在深圳召开
  15. 台式计算机系统错误,台式电脑开机蓝屏,代码是0×0000006B,怎么修复?
  16. vscode恢复被误删的文件
  17. matlab旧版比新版好用,MATLAB新版本及新功能介绍matlab2012b.PDF
  18. x的根号下三次方用C++怎么打
  19. 腾讯云启动数据库进程,提示No such host is known
  20. 分布计算系统学习随笔 第六章分布式系统中的死锁

热门文章

  1. 深度学习——L0、L1及L2范数
  2. IOI2017 古书books
  3. 微信小程序之生成条形码和二维码
  4. 手机相机图像对比工具开发
  5. 购置税用计算机怎么算,2019车辆购置税新政策(计算器+如何计算+计算公式)
  6. pgsql中distinct on的用法
  7. 2020_9_25_数字和列表
  8. 蓝桥杯练习【STL训练】——周瑜的反间计
  9. word文件做一半未响应_Win7的word为什么老是出现未响应?
  10. 两计算机网线连接打印机共享打印机共享打印机,两台计算机用网线相连共享打印机...