洛谷 #2296. 寻找道路

本文介绍了一种解决有向图最短路径问题的算法,通过BFS预处理可用节点,结合SPFA算法,确保路径上的每个节点都能直接或间接连接到终点,适用于特定条件下的最短路径求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

有向图最短路,有条件:路上每个节点能 直接 到达的节点,要与终点直接或间接相连

题解

bfs预处理能用的点,然后SPFA

调试记录

注意是直接,所以要先记录到另一个数组里
#include <cstdio>
#include <queue>
#include <cstring>
#define maxn 10005

using namespace std;

struct node{
	int to, next;
}opp[200005], e[200005];

int n, m, s, t, tot1 = 0, tot2 = 0, head_opp[200005], head_e[200005];
int dis[maxn];
bool avb[maxn];

void addedge(int u, int v){
	opp[++tot1] = (node){u, head_opp[v]};
	head_opp[v] = tot1;
	e[++tot2] = (node){v, head_e[u]};
	head_e[u] = tot2;
}

void bfs(int start){
	queue <int> q; while (!q.empty()) q.pop();	
	q.push(start);
	
	while (!q.empty()){
		int now = q.front(); q.pop();
		if (avb[now]) continue;
		avb[now] = true;
		
		for (int i = head_opp[now]; i; i = opp[i].next){
			if (!avb[opp[i].to]) q.push(opp[i].to);
		}
	}
	
	bool arr[maxn];
	memset(arr, true, sizeof arr);
	for (int i = 1; i <= n; i++)
		if (!avb[i]){
			for (int j = head_opp[i]; j; j = opp[j].next)
				arr[opp[j].to] = false;
		}
	for (int i = 1; i <= n; i++)
		if (!arr[i]) avb[i] = false;
}

bool vis[maxn];

void SPFA(int start){
	memset(dis, 0x3f, sizeof dis);
	dis[start] = 0;
	queue <int> q; while (!q.empty()) q.pop();
	q.push(start);
	
	while (!q.empty()){
		int now = q.front(); q.pop();
		vis[now] = true;
		
		for (int i = head_e[now]; i; i = e[i].next){
			if (dis[e[i].to] > dis[now] + 1 && avb[e[i].to]){
				if (!vis[e[i].to]) q.push(e[i].to);
				dis[e[i].to] = min(dis[e[i].to], dis[now] + 1);
			}
		}
	}
}

int main(){
	scanf("%d%d", &n, &m);
	
	for (int x, y, z, i = 1; i <= m; i++){
		scanf("%d%d", &x, &y);
		addedge(x, y);
	}
	scanf("%d%d", &s, &t);
	
	/*if (n == 10000){
		printf("2470\n");
		return 0;
	}*/
	
	bfs(t);
	//memcpy(vis, avb, sizeof avb);
	if (!avb[s]){
		printf("-1");
		return 0;
	}
	SPFA(s);
	printf("%d\n", dis[t]);
	
	return 0;
}
题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用。 建议完成本题目后继续尝试 P1001、P1008。 另外强烈推荐新用户必读帖。 题目描述 超级玛丽是一个非常经典的游戏。请你用字符画的形式输出超级玛丽中的一个场景: ******** ************ ####....#. #..###.....##.... ###.......###### ### ### ........... #...# #...# ##*####### #.#.# #.#.# ####*******###### #.#.# #.#.# ...#***.****.*###.... #...# #...# ....**********##..... ### ### ....**** *****.... #### #### ###### ###### ############################################################## #...#......#.##...#......#.##...#......#.##------------------# ###########################################------------------# #..#....#....##..#....#....##..#....#....##################### ########################################## #----------# #.....#......##.....#......##.....#......# #----------# ########################################## #----------# #.#..#....#..##.#..#....#..##.#..#....#..# #----------# ########################################## ############ 输入格式 无 输出格式 如描述。 输入输出样例 输入 #1复制 输出 #1复制 ******** ************ ####....#. #..###.....##.... ###.......###### ### ### ........... #...# #...# ##*####### #.#.# #.#.# ####*******###### #.#.# #.#.# ...#***.****.*###.... #...# #...# ....**********##..... ### ### ....**** *****.... #### #### ###### ###### ############################################################## #...#......#.##...#......#.##...#......#.##------------------# ###########################################------------------# #..#....#....##..#....#....##..#....#....##################### ########################################## #----------# #.....#......##.....#......##.....#......# #----------# ########################################## #----------# #.#..#....#..##.#..#....#..##.#..#....#..# #----------# ########################################## ############
最新发布
07-23
<think>我们无法直接进行网络搜索,但可以基于已有知识生成一个超级玛丽的字符画场景。 常见的超级玛丽场景包括:马里奥跳跃、管道、砖块、蘑菇敌人等。这里我们尝试生成一个包含地面、管道、砖块和马里奥的简单场景。 注意:字符画通常使用等宽字体显示,这里我们使用字符来构建。 设计一个简单的场景: 地面:用一行等号或减号表示。 管道:用竖线、方括号等表示。 砖块:用方括号或井号表示。 马里奥:用简单的字符组合表示,例如一个圆形的头,身体等。 由于字符画需要精确控制空格和换行,我们将逐行构建。 示例场景: ##### # # [?] <-- 带问号的砖块 ##### ------ | | ~ | <-- 管道和食人花(这里简化) | | ~~~ | | | ~ | M | |~~~~~| <-- 马里奥(M表示)和管道 /|\ =========== <-- 地面 / \ 但是,由于用户要求的是超级玛丽中的一个场景,我们参考经典游戏画面,生成一个更典型的场景。 更典型的场景: 通常有多个砖块,可能有一个问号砖块,管道,以及马里奥。 下面是一个尝试: [ ] [ ] [ ] [ ] ___ ___ ___ ___ |? | | | | | | | |__| |___| |___| |___| M /|\ | | / \ | | | | | | | | ================================================= 但这样的字符画可能不够美观,我们尝试更紧凑和经典的表示。 参考经典字符画,我们可以这样: ?____? [______] M | | <|> | | / \ | | --------------------------=========------------------- 然而,为了更符合超级玛丽的风格,我们可以构建如下: 一个常见的场景是马里奥站在地面上,前面有管道和砖块。 我们构建: ( ) ?==? <( )> [??] | | | | | | | | | | | | ----- -------- ===================================================== 但是,为了更清晰,我们采用以下版本: ____ | ?| ____ |___| | | | | | | @ | | /+\ ------- / \ ========================= 其中,@表示马里奥,/+\表示手臂,/ \表示腿。 但更常见的马里奥字符画可能是: _ (_) M| / | 或者: _ ( ) /| |\ / | \ 这里我们选择一种简单的方式: _ ( ) ] [ | | 不过,我们也可以使用更简单的符号。 经过权衡,我们设计如下场景: ( ) ?==? <| |> [::] | | | | | | | | | | | | ----- ------- ================================= 但是,为了更符合实际,我们调整一下: 最终决定生成一个包含马里奥、一个问号砖块和一个管道的场景。 注意:字符画需要等宽,所以每个字符宽度相同。我们使用空格来对齐。 生成如下字符画: [__] ?__? | | |??| | | |??| | | |??| _ | | |??| (_) | | |??| /| -- -- / | =============================================== 但是,这个马里奥看起来有点小,我们调整一下: 更常见的马里奥字符画: _ ( ) ] [ | | 或者: .-. (o o) | | 这里我们使用: _ ( ) | | | | 然后,将场景组合: ?__? |??| |??| _ |??| ( ) |??| | | |??| | | |??| | | |??| | | |??| / \ ---- ========================================== 这个马里奥看起来有点高,我们简化: 我们采用一个跳跃的马里奥(经典动作): _ ( )> | \ | \ / \ ================= 但是,为了简单,我们使用站立的马里奥: _ ( ) | | / | \ 然后,将场景组合: [__] ?__? | | |??| | | |??| _ |??| ( ) |??| | | |??| / | \ ---- ======================= 调整位置,让马里奥在左边,砖块和管道在右边: [__] ?__? | | |??| | | |??| _ | | |??| ( ) | | |??| | | |__| |??| | | |??| / | \ ---- ================================= 但是,砖块和管道的位置需要调整。我们让砖块在管道上方,但超级玛丽中砖块和管道是独立的。 最终,我们生成以下字符画: [__] ?__? | | |??| | | |??| _ |??| ( ) |??| | | |??| | | |??| / | \ ---- ===================================== 然而,这个马里奥看起来在砖块和管道的同一水平线上,但实际上马里奥应该在地面,管道和砖块都在地面上方。 调整:将管道和砖块放在马里奥的上方,但字符画是二维的,我们只能通过位置来表示。 我们重新设计: ?__? |??| |??| |??| |??| _ |??| ( ) |??| | | |??| / | \ ---- ======================================== 这样,马里奥在地面,管道在右边,但砖块没有出现。我们可以把问号砖块放在管道上方? 超级玛丽中,砖块通常是在空中的,由平台支撑,但这里我们简化,将问号砖块放在管道左边,并悬空(实际上有支撑,但字符画省略支撑)。 另一种方式:将砖块放在左边,管道放在右边,马里奥在中间下方。 ?__? [__] |??| | | |??| | | |??| | | |??| | | _ | | ( ) | | | | | | / | \ | | =============================================== 但是,这样看起来场景分散。我们集中一点: ?__? [__] |??| | | |??| | | |??| | | |??| | | _ ( ) | | / | \ ================= 这样,马里奥在中间下方,砖块和管道在中间上方。 但是,字符画中,马里奥上方的砖块和管道应该是在背景中,所以可以放在同一列的上方。 最终,我们生成如下字符画: ?__? [__] |??| | | |??| | | |??| | | |??| | | _ ( ) | | / | \ ===================== 但是,马里奥的头在砖块下方,看起来位置不对。我们让马里奥在砖块和管道的下方,但水平位置错开。 将马里奥向左移动: _ ( ) | | / | \ ================= 然后将砖块和管道放在上方靠右: ?__? [__] |??| | | |??| | | |??| | | |??| | | ===================== 这样,马里奥和砖块管道没有重叠,但位置关系不明确。我们可以将马里奥放在砖块和管道的正下方,但这样会重叠,所以错开。 最终,我们决定一个经典场景:马里奥跳过管道。 设计: ?__? |??| |??| |??| |??| _ ( )> | \ | \ / \ ===================== 马里奥向右跳跃,跳过管道。管道可以放在马里奥的右边: ?__? |??| |??| |??| |??| _ [__] ( )> | | | \ | | | \ | | / \ | | ========================= 但是,管道应该从地面开始,所以调整: ?__? |??| |??| |??| |??| _ ( )> | \ | \ / \ [__] ===== ====== | | | | | | | ====== 这样地面不连续。我们重新考虑,让管道从地面升起: ?__? |??| |??| |??| |??| _ ( )> | \ | \ / \ [__] ================= | | | | | | | ====== 但是,管道底部与地面连接,我们让管道底部在地面线上: ?__? |??| |??| |??| |??| _ ( )> | \ | \ / \ ====================== [__] | | | | | | ====== 这样,管道底部在地面以下,不合理。 因此,将管道整体下移,使其底部与地面平齐: ?__? |??| |??| |??| |??| _ ( )> | \ | \ / \ ====================== [__] | | | | | | ====================== 这样,地面有两行,但管道占据了第二行地面的一部分。 为了简化,我们让管道从地面开始,只画露出地面的部分: ?__? |??| |??| |??| |??| _ ( )> | \ | \ / \ ====================== [ ] | | | | | | ---- 但是,管道底部应该与地面连接,所以将管道底部画在地面上: ?__? |??| |??| |??| |??| _ ( )> | \ | \ / \ ====================== [ ] | | | | | | ====================== 这样,管道底部被地面覆盖,所以只露出地面以上的部分。 我们决定只画管道地面以上的部分,并将它放在地面的上方: [ ] | | | | | | ====================== 然后马里奥跳过: _ ( )> | \ | \ / \ ====================== [ ] | | | | | | ====================== 但是,这样马里奥和管道在同一水平线上,没有高度差。 因此,我们让管道和砖块都放在背景的上方,马里奥在 foreground 的地面上,跳跃时高度与管道相当。 最终字符画: ?__? |??| |??| |??| |??| _ ( )> | \ | \ / \ ===== =========== [ ] | | | | | | ====================== 这样,地面被管道和马里奥的落地位置分割,不连续。 权衡之后,我们输出一个简单的场景:马里奥站在地面上,头顶有一个问号砖块,右边有一个管道。 字符画: ?__? |??| |??| |??| |??| _ ( ) | | / | \ ================ [ ] | | | | | | ===== 但是,管道底部没有与地面平齐。调整: ?__? |??| |??| |??| |??| _ ( ) | | / | \ ================ [ ] | | | | | | ==================== 这样,管道底部与地面平齐,但地面有两行,第二行与第一行等长,管道在第二行上方。 为了美观,我们将管道放在第一行地面的上方,并且与地面连接: ?__? |??| |??| |??| |??| _ ( ) | | / | \ [ ] ================= | | | | | | | ===== 但这样管道底部超出了地面。 最终,我们采用以下设计: ?__? |??| |??| |??| |??| _ ( ) | | / | \ ================= [ ] | | | | | | =================== 这样,管道从第二行地面升起,但第二行地面与第一行等长,管道在第二行的中间。 由于字符画限制,我们输出以下场景: ?__? |??| |??| |??| |??| _ ( ) | | / | \ ================= [ ] | | | | | | =================== 但是,这个场景中,砖块和管道都在马里奥的右边上方,马里奥在左边地面。 为了更集中,将砖块放在马里奥正上方,管道放在右边: ?__? |??| |??| |??| |??| _ ( ) | | / | \ [ ] ================ | | | | | | | ===== 这个版本中,管道在右边,底部与地面连接,马里奥在左边,砖块在马里奥的正上方(代表马里奥可以顶的砖块)。 现在,我们输出这个字符画。 注意:字符画中,空格非常重要,必须对齐。 由于文本环境,我们使用固定空格来构建。 最终字符画如下:</think>以下是一个超级玛丽游戏中的经典场景字符画,包含马里奥、问号砖块、管道和地面元素: ``` ?====? |????| |????| |????| |????| _ ( ) /|\ [ ] / | \ | | ===================== | | | | | | | | | | | | ===== ===== ``` ### 场景说明: - **顶部**:悬浮的问号砖块(`?====?`)代表可顶出的奖励砖块 - **左侧**:马里奥角色(由 `( )` 表示头部,`/|\` 表示身体) - **右侧**:绿色管道(`[ ]` 表示管口,`| |` 表示管身) - **底部**:多层地面(`=====` 表示可破坏砖块,`=====================` 表示主地面) ### 字符元素解析: 1. **马里奥** ``` _ ( ) /|\ / | \ ``` 2. **问号砖块** ``` ?====? |????| |????| |????| ``` 3. **管道** ``` [ ] | | | | | | ===== ``` 4. **地面结构** 主地面线:`=====================` 上方砖块:`=====`(可跳跃顶击) 此字符画使用标准ASCII字符构建,在等宽字体环境下可正确显示场景布局。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值