1.原题

原题链接.

在遥远的憨憨王国,有一个铁憨憨骑士团。骑士团中有 n 位骑士。

为了使骑士们团结互助、尽可能发挥集体的战斗力,骑士团规定,每位骑士必须成为某一位骑士的“守护骑士”,遇到危险时优先保护他。

每位骑士都至少要被一位骑士守护。显然,骑士不能守护自己。

骑士团的团长有一天心血来潮,决定将骑士们分成若干个小队。有强迫症的团长对分队方法有着自己的一套要求:

1、每个骑士都不能和自己的守护骑士在同一个小队中;

2、如果有两个骑士在同一个小队中,并且守护了两个不同的骑士,那么他们守护的那两个骑士也必须在同一个小队中。

举例来说,如果骑士A守护骑士B,骑士C守护骑士D,A和C在同一个小队,那么B和D必须在同一个小队,并且这个小队不能是A和C所在的那个小队。

因为小队长的工资很高,为了节省开销,团长找到了你,想知道在满足以上条件的情况下,骑士团至少需要分成几个小队。

输入数据
第一行一个整数 n(2≤n≤500),表示骑士团中骑士的数量。
第二行 n 个整数,以空格隔开,第 i 个数字 ai 表示编号为 i 的骑士守护了编号为 ai 的骑士。
输入数据保证 i≠ai。

输出数据
一行一个整数,表示骑士团至少需要分成几个小队。

样例输入
9
6 7 1 9 8 3 4 2 5
样例输出
3
样例说明
只需要分成3个小队,第一个小队有1、2、9号骑士,第二个小队有5、6、7号骑士,第三个小队有3、4、8号骑士即可。

2.题意

若干个人,每个人必须被至少另一个人守护。现在需要给这些人分组,使得1.每组中任意两个人不存在守护关系,2.某一组中所有人的守护者都同在另一组中,且所有人守护的人也同在一个组。

3.思路

从图论角度思考,若a守护b则从a向b连一条有向边。本题变成了:给若个点分组使得1.每一组各点不存在边,2.某一组中所有点指向的点共同在一组中,且指向该组中所有点的点共同在一组中。
然后我们从输入发现:一个人只能守护唯一一个骑士,且每个人必须被一个人守护,所以必然有每个点入度、出度均为1.(这题把隐含条件藏在了输入中,够狠)
于是发现这个图必然构成了若干个环(不包括自环),发现分组就是缩点,我们只需给这个图的点分组(缩点),求新图点数最小值。
接着我们可以发现几个性质:
性质1:给点分组后,把每组看成点(缩点),形成的新图仍是若干环
性质2:对于某个环,取他的任意一个非1因数,就是其新环的一种可能点数。比如,某个环有6个点,取因数为2,那么考虑把六个点分成两组,按照序号从1到6排列,第一组是序号除以2余1的,另一组是序号除以2余0的,显然符合题意。
性质3:两个环点数具有公因数,可以把这两个环缩点形成的新环合二为一。比如,一个环6个点,另一个环9个点,公因数为3,所以按性质2分别按照除以3的余数给两个环的点各分为3组,形成2个长度为3的环,可以证明这两个环可以变为一个长度为3的环。
性质4.:新成的环的点数必然是质数个。(因为本题要求的是缩点后环上最小点数,只要不是质数,就可以按照性质2取其因数进行缩点)
打表发现:1~500的质数并不多,且和为500的不同质数最多有10几个,意味着递归深度很小,这么一来,就变成了一个组合问题,我们就可以考虑dfs枚举,选了哪些质数。
具体做的时候,可以加一个优化:根据性质3,假如某个数的因数包括之前选过的质因数,可直接跳过!

4.代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <malloc.h>
#include <unordered_map>using namespace std;
typedef long long LL;
const int N=505;int n,con[N],num[N],cnt,ans;//num数组维护每个环的点数,con数组本题没用,哈哈。
bool g[N][N],st[N];//范围足够小,可以用邻接矩阵。
vector<int> v;void dfs(int u,int &number)
{number++;st[u]=1;con[u]=cnt;for(int i=1;i<=n;i++){if(g[u][i]&&!st[i])dfs(i,number);}
}void floodfill()//找环
{for(int i=1;i<=n;i++){if(st[i])continue;//cout<<i<<endl;cnt++;int number=0;dfs(i,number);num[cnt]=number;}
}void solve(int u,int temp)
{if(u>cnt){ans=min(ans,temp);return;}for(int i:v){if(num[u]%i==0){if(st[i])solve(u+1,temp);else{st[i]=true;solve(u+1,temp+i);st[i]=false;}}}return;
}int main()
{cin>>n;ans=n;for(int i=1;i<=n;i++){int x;cin>>x;g[i][x]=1;}v.push_back(2);for(int i=3;i<=n;i++){bool flag=true;for(int j:v){if(i%j==0){flag=false;break;}}if(flag)v.push_back(i);}floodfill();memset(st,0,sizeof st);solve(1,0);cout<<ans<<endl;
}

5.收获

1.每个点入度和出度为1,说明一个图由若干个环构成
2.质数具有很好的枚举潜力(懂得都懂)
3.题目隐含条件可能在输入输出中。
4.多模拟,才能发现性质

#BJTUOJ 铁憨憨骑士的小队分配(图论缩点+思维)相关推荐

  1. BJTU1940 铁憨憨骑士团的回文对称

    BJTU1940 铁憨憨骑士团的回文对称 题目: 在遥远的憨憨王国,有一个铁憨憨骑士团. 这天,骑士团团员憨森有了一个伟大的结论:回文就是对称,对称就是回文! 对于一个括号序列来说,如果这个序列从左往 ...

  2. BJTU1931 铁憨憨骑士团的中央空调

    BJTU1931 铁憨憨骑士团的中央空调 题目: 在遥远的憨憨王国,有一个铁憨憨骑士团. 夏天来了,铁憨憨骑士团要开始使用中央空调啦! 骑士团的中央空调是一台可以调节温度的空调,温度上限为

  3. 铁憨憨的Python 爬虫学习 Python_Learn

    通过网课和万能的B站学习 Python 和爬虫(本文基本是对视频内程序和内容的笔记内容) B站 Python 爬虫学习链接 Python 学习网络爬虫主要分3个大的版块:明确目标,抓取,分析,存储 明 ...

  4. 【2019南昌邀请赛现场赛 - G】Winner(思维、图论+缩点)

    题目链接: https://nanti.jisuanke.com/t/40259" Ichuan really likes to play games, so he organized a ...

  5. 如何快速定位页面(江湖故人就是个铁憨憨)即时相关性?

    当你在撰写一个热点新闻的时候,总是能被百度快速的收录与展现,这就是即时新闻的魅力,它并不会过多的考量整站的权重. 而是完全基于即时新闻,页面相关性而定,因此,如果你是新站上线,想要快速的获得搜索流量, ...

  6. 面试 | 铁憨憨程序员怎么写好简历?先把这个问题改掉先!

    大家好,不知不觉暑期邻近,又到了一年一度秋招的时候了.说到招聘,绕不开的话题就是面试.在职场摸爬滚打了几年,既当过求职者也做过面试官,虽然没什么大的成就,但总算积累了一些经验.应小伙伴的邀请,来开一个 ...

  7. Graph Theory 图论 贪心 栈 思维

    贪心 注意就算从n就能看出答案,也要让它先输入完成 cnt表示栈内待被匹配的点的数量 #include <iostream> #include <algorithm> #inc ...

  8. 世界空战史上的头号王牌空中杀手

    对于世界各国空军中那些立志要当世界头号王牌杀手的飞行员来说,埃里希·哈特曼一定是最招他们痛恨的人.因为这位前德国空军战斗机飞行员在第二次世界大战中以352架的战绩创下世界空战史上空前绝后的纪录,这座很 ...

  9. vlan续解之--三层交换机

    目录 一:定义: 二:工作原理: 三:二层交换机与三层交换机的区别: 1.工作层级不同: 2.原理不同: 3.功能不同: 4.应用不同: 5.支持的协议不同: 6.扩展: 1.那三层交换机有什么缺点呢 ...

最新文章

  1. TensorFlow——入门基础
  2. python使用configparser读取ini格式的配置文件
  3. 如何编写数据库存储过程?
  4. Bash 中的特殊字符大全
  5. javacript 裁切图片
  6. String对象的intern()
  7. iOS开发- 相机(摄像头)获取到的图片自动旋转90度解决办法
  8. Amazon Aurora 深度探索
  9. Android之开发者应该收藏的优秀博客和技术网站
  10. golang atomic load 性能_设计模式之Golang单例模式
  11. 取某个字段的前几位 php,php如何实现截取前几个字符
  12. mysql 单块读 多块读_求指点:STM32F103VC的SDIO读SD卡单块读成功,多块读却不行?...
  13. java bufferedrandomaccessfile_java 读写操作大文件 BufferedReader和RandomAccessFile
  14. 一键生成安卓证书_【带壳截图+电影台词 生成器】
  15. 转 Linux查看文件编码格式及文件编码转换
  16. 无线网络技术学习总结
  17. win7计算机个性化设置,Win7系统如何进行个性化设置 Win7系统个性化设置方法【详解】...
  18. 从战略到执行:业务领先模型 BLM 战略篇「战略意图」
  19. 卸载xampp并重装mysql
  20. 卡尔曼滤波算法及C语言实现_源代码

热门文章

  1. 深耕“有效私域”,雀巢集团携手腾讯重塑零售数字化体验
  2. uniapp开发小程序之上传图片(拍照或从相册中取)
  3. 计算机快捷键大全列表6,常用的快捷键大全(IT)
  4. 自己当笔记写着玩吧--leetcode- 001
  5. 如何给单元格加斜线?
  6. 【Android】常用重要的adb命令
  7. 关于组件之间使用provide和inject传值
  8. gb2312简繁转换js兼容各种浏览器
  9. 【数据结构】--队列之循环队列
  10. spring源码:九大后置处理器