洛谷 P2921 在农场万圣节Trick or Treat on the Farm题解
题意翻译
题目描述
每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节。
由于牛棚不太大,FJ通过指定奶牛必须遵循的穿越路线来确保奶牛的乐趣。为了实现这个让奶牛在牛棚里来回穿梭的方案,FJ在第i号隔间上张贴了一个“下一个隔间”Next_i(1<=Next_i<=N),告诉奶牛要去的下一个隔间;这样,为了收集它们的糖果,奶牛就会在牛棚里来回穿梭了。
FJ命令奶牛i应该从i号隔间开始收集糖果。如果一只奶牛回到某一个她已经去过的隔间,她就会停止收集糖果。
在被迫停止收集糖果之前,计算一下每头奶牛要前往的隔间数(包含起点)。
输入格式
第1行 整数n。
第2行到n+1行 每行包含一个整数 next_i 。
输出格式
n行,第i行包含一个整数,表示第i只奶牛要前往的隔间数。
样例解释
有4个隔间
隔间1要求牛到隔间1
隔间2要求牛到隔间3
隔间3要求牛到隔间2
隔间4要求牛到隔间3
牛1,从1号隔间出发,总共访问1个隔间;
牛2,从2号隔间出发,然后到三号隔间,然后到2号隔间,终止,总共访问2个隔间;
牛3,从3号隔间出发,然后到2号隔间,然后到3号隔间,终止,总共访问2个隔间;
牛4,从4号隔间出发,然后到3号隔间,然后到2号隔间,然后到3号隔间,终止,总共访问3个隔间。
翻译提供者:吃葡萄吐糖
题目描述
Every year in Wisconsin the cows celebrate the USA autumn holiday of Halloween by dressing up in costumes and collecting candy that Farmer John leaves in the N (1 <= N <= 100,000) stalls conveniently numbered 1..N.
Because the barn is not so large, FJ makes sure the cows extend their fun by specifying a traversal route the cows must follow. To implement this scheme for traveling back and forth through the barn, FJ has posted a 'next stall number' next_i (1 <= next_i <= N) on stall i that tells the cows which stall to visit next; the cows thus might travel the length of the barn many times in order to collect their candy.
FJ mandates that cow i should start collecting candy at stall i. A cow stops her candy collection if she arrives back at any stall she has already visited.
Calculate the number of unique stalls each cow visits before being forced to stop her candy collection.
POINTS: 100
输入格式
* Line 1: A single integer: N
* Lines 2..N+1: Line i+1 contains a single integer: next_i
输出格式
* Lines 1..N: Line i contains a single integer that is the total number of unique stalls visited by cow i before she returns to a stall she has previously visited.
输入输出样例
4
1
3
2
3
1
2
2
3
说明/提示
Four stalls.
* Stall 1 directs the cow back to stall 1.
* Stall 2 directs the cow to stall 3
* Stall 3 directs the cow to stall 2
* Stall 4 directs the cow to stall 3
Cow 1: Start at 1, next is 1. Total stalls visited: 1.
Cow 2: Start at 2, next is 3, next is 2. Total stalls visited: 2. Cow 3: Start at 3, next is 2, next is 3. Total stalls visited: 2. Cow 4: Start at 4, next is 3, next is 2, next is 3. Total stalls visited: 3.
题解
这个题虽然是图的题目,但是它的图很特殊,每个节点的出度都是1,而且一定存在环。
直接暴力可以得40分。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h> using namespace std; const int MAXN = 1e5 + ;
int n, next[MAXN], vis[MAXN], ans[MAXN], p; int main()
{
cin >> n;
for(int i = ; i <= n; i++)
{
cin >> next[i];
}
for(int i = ; i <= n; i++)
{
memset(vis, , sizeof(vis));
ans[i] = ;
p = i;
vis[p] = ;
while(vis[next[p]] == )
{
vis[next[p]] = ;
p = next[p];
ans[i]++;
}
}
for(int i = ; i <= n; i++)
{
cout << ans[i] << endl;
} return ;
}
剩下的问题就是如何解决TLE的问题。和01迷宫问题的思路类似,需要对图进行染色,找到环,同一个环上的各个节点的隔间数是相同的,把这个结果保存下来就可以减少后续的运算量了。下图是样例染色的结果。1号节点是个自环长度为1,2和3号节点是长度为2的环,所以这两个节点输出的隔间数都是环的长度2。4号节点经过1步走到2和3组成的环,所以它的隔间数是1+2=3。

染色的过程有两种可能:
1)染色的过程遇到了同种颜色的节点,例如下图中2-3-4-3。
2)染色的过程中遇到了不同颜色的节点,例如下图中的5-2和6-4。

为了方便计算环的长度和走过的隔间数,我们引入两个变量:cnt和dfn数组。cnt从0开始,用于计算此次染色所经过的隔间数,每走一次加1。dfn记录每个节点和此次染色第一个节点之间的距离。例如第一种染色情况,dfn(2)=0,dfn(3)=1,dfn(4)=2。当从4走到3时,我们立刻可以发现一个同色节点组成的环。环的长度是cnt-dfn(3)=2。而且我们可以记录下这个颜色路径进入环的第一个节点是3号节点。
对于第2种染色过程,又分为两种情况:
1)所遇到的不同颜色的节点在环上,如4号节点。这种情况隔间数等于cnt+环长。
2)所遇到的不同颜色的节点不在环上,如2号节点。这种情况隔间数等于cnt+环长+从所遇到的节点到第一个进入环的节点的距离。
而判断节点是否在环上,可以用dfn的大小进行比较,所有比第一个进入环的节点的dfn小的节点都在环外,反之在环上。
下面就是改进后的代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h> using namespace std; const int MAXN = 1e5 + ;
int n, next[MAXN], vis[MAXN], ans[MAXN], p;
int dfn[MAXN], cnt;
int looplen[MAXN]; // 环长
int stloop[MAXN]; // 路径中进入环的第一个节点的dfn值 int main()
{
cin >> n;
for(int i = ; i <= n; i++)
{
cin >> next[i];
} memset(vis, , sizeof(vis));
for(int i = ; i <= n; i++)
{
cnt = ;
p = i;
while(vis[p] == )
{
vis[p] = i;
dfn[p] = cnt;
p = next[p];
cnt++;
}
if(vis[p] == i)
{ // 走到了自己染色的环
ans[i] = cnt;
looplen[i] = cnt - dfn[p];
stloop[i] = dfn[p];
}
else
{ // 走到了其他点染色的路径
looplen[i] = looplen[vis[p]];
stloop[i] = cnt;
if(stloop[vis[p]] > dfn[p])
{ // 遇到的点不在环上
stloop[i] += stloop[vis[p]] - dfn[p];
}
ans[i] = stloop[i] + looplen[i];
}
}
for(int i = ; i <= n; i++)
{
cout << ans[i] << endl;
} return ;
}
洛谷 P2921 在农场万圣节Trick or Treat on the Farm题解的更多相关文章
- C++ 洛谷 P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 题解
P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 分析: 这棵树上有且仅有一个环 两种情况: 1.讨论一个点在环上,如果在则答案与它指向点相同, 2 ...
- 缩点【洛谷P2921】 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
[洛谷P2921] [USACO08DEC]在农场万圣节Trick or Treat on the Farm 题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N< ...
- 洛谷——P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 题意翻译 题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N< ...
- LGOJ P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
今天我来给大家带来一片蒟蒻题解 ~~真香 LGOJ P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 题目描述 每年,在威斯康星州,奶牛们都会穿上 ...
- P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm(Tarjan+记忆化)
P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 题意翻译 题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N< ...
- 「USACO08DEC」「LuoguP2921」在农场万圣节Trick or Treat on the Farm(tarjan
题意翻译 题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节. 由于牛棚不太大,FJ通过指定 ...
- 洛谷 P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节. 由于牛棚不太大,FJ通过指定奶牛必须遵 ...
- [USACO08DEC]在农场万圣节Trick or Treat on the Farm【Tarja缩点+dfs】
题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节. 由于牛棚不太大,FJ通过指定奶牛必须遵 ...
- [洛谷P2921][USACO08DEC]在农场万圣节Trick or Treat on the Farm
题目大意:给你一张有向图,每个点最多一条出边,问从每个开始,走多少步会到一个已经过的点 题解:$tarjan$缩点,然后建反图$DP$ 卡点:无 C++ Code: #include <cstd ...
随机推荐
- 大数据 -- zookeeper和kafka集群环境搭建
一 运行环境 从阿里云申请三台云服务器,这里我使用了两个不同的阿里云账号去申请云服务器.我们配置三台主机名分别为zy1,zy2,zy3. 我们通过阿里云可以获取主机的公网ip地址,如下: 通过secu ...
- 使用抓包工具将抓到的接口存放Jmeter中
1. jmeter工作台新增 HTTP代理服务器.端口设置为:8888 2. 抓包工具上面设置代理服务器地址 3.代理服务器未启动时,抓包工具界面显示无法联网. 4.在Jmeter中点击[启动]HTT ...
- 为什么重写equals时一定要重写hashcode
我们开发时写一个类,默认继承Object类,Object类的equals方法是比较是否指向同一个对象(地址是否相同), Object类 的hashcode方法返回的对象内存地址的值, 一个类只重写了e ...
- flutter本地环境的安装以及编辑器的配置
由于本文图片比较多,所有都缩小了不少,点击图片就可以放大看到原始图片 使用镜像 cmd打开终端,贴上以下代码,以加入到环境变量中,如果添加失败,可以手动添加 export PUB_HOSTED_URL ...
- 今天七夕节,外面下着大雨,用Python的tkinter做一个下爱心雨的特效,发给妹子
今天七夕,还下着雨,刚好想做一个下着爱心雨的特效 准备图片素材 1.美图秀秀找一个爱心图,大小就50*50就可以,生成的是一个png格式文件 2.由于canvas.create_image只支持gif ...
- python:实现几种排序算法
冒泡排序 比较相邻两个字符,如果左边大于右边,则交换位置,遍历一遍字符后,则最大的肯定在最右边:继续循环处理剩下的字符(最右边的不用再比较了,已经最大了) 代码实现: def BubbleSort(s ...
- 重置 Bootstrap modal 模态框数据
利用 Bootstrap modal 模态框弹层添加或编辑数据,第二次弹出模态框时总是记住上一次的数据值,stackoverflow 上找到个比较好的方法,就是利用 jQuery 的 clone 方法 ...
- 三伏天里小试牛刀andriod 开发 #华为云·寻找黑马程序员#【华为云技术分享】
2019年07月,北京,三伏天,好热啊.越热自己还越懒得动换(肉身给的信号),但是做为产品经理/交互设计师的,总想着思考些什么(灵魂上给的信号),或者是学习些什么,更有利于将来的职业发展吧,哈哈哈.工 ...
- Ambari调整日志级别:How to enable debug logging in Ambari Server and Ambari Agent ?
PURPOSE When troubleshooting Ambari issues, it may be necessary to enable debug logging in the Ambar ...
- 华为、华三 交换机 开启SNMP 简单网络管理协议
[huawei]snmp-agent //使能SNMP代理 [huawei]snmp-agent sys-info version all //允许所有SNMP 支持 协议 [huawei]snmp- ...