1262(构造)(bfs无边权最短路)(E - Nearest Black Vertex

这篇具有很好参考价值的文章主要介绍了1262(构造)(bfs无边权最短路)(E - Nearest Black Vertex。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

E - Nearest Black Vertex (atcoder.jp)

题面

如果无法将每个顶点绘制为黑色或白色以满足条件,请打印 No.否则,打印 Yes

如果顶点 i is painted black and 被漆成黑色 00 if white. 如果是白色。

第一行是否有解,YES NO
第二行字符串1是黑,0是白。
连通无向图 不包含自环和多边

第i条边链接ui和vi,
至少有一个顶点绘制为黑色。
pi和黑色点的最小距离是di

u和v的距离是u和v路径上的最小边数量

无向图 不包含自环和多边
至少有一个顶点绘制为黑色。
pi和黑色点的最小距离是di
边权为1

黑色点特殊点,先假设一个点是特殊点,再跑下最短路,看是否满足所有的d条件。
但是这样不一定可以确定一个特殊点,d可能需要多个特殊点同时存在才能满足。

有解情况没想法。

无解情况,只有一个点时,如果d!= 0无解
两个点,如果d != 1或0,无解
3个点,d要>=0 <= 2,


所以d要>= 0,<= n-1;

题解思路:

用bfs搜点,< d的标记为白
再搜一次,如果不存在>= d的就NO,用bool数组记录情况,最后一边遍历一边输出就可以实现用所谓的“string”来表示点的信息。

题目问的棋子是否符合要求:
首先是需要得到黑白棋子的情况。

白棋和黑棋两个对立面,可以随便选一个来操作。
这里选白棋来接受操作。

要知道哪个可以作黑棋很难,这时可以反着想,
哪个不能做黑棋?题目对黑棋做了什么限制?

给了k个棋子,要求与这些棋子距离最近的黑棋子的距离为di,所以
距离这些棋子的距离小于di的是不能作为白棋子的,全部标记为黑棋子,其余标记为白棋子,这样就得到了黑白情况了。

然后,题目要距离白棋子最近的黑棋子距离=di,再处理每一个棋子和黑棋子的最短距离。
对应求一种点到另一种点的最短距离套路,看距离是否=di就行了。不符合输出no然后return
全部处理完后再输出yes

代码与分析
jls代码
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
long long 简写

int main() {

    int N, M;
    cin >> N >> M;
    ***
    vector<vector<int>> adj(N);
    还以为是什么函数,其实是数组名
    for (int i = 0; i < M; i++) {
        int u, v;
        cin >> u >> v;
        u--, v--;
        vector下标从0开始,uv是1开始,所以u--,v--
        adj[u].push_back(v);
        adj[v].push_back(u);
                权值都为1,没必要储存,所以第二维直接pb,遍历时可以用迭代,不用把整个N都遍历,

	}
    ***
    vector<bool> black(N, true);
    大小为N,初始值为true的vector
    int K;
    cin >> K;
    
    vector<int> p(K), d(K);
    大小为k的p,d vector
    for (int i = 0; i < K; i++) {
        cin >> p[i] >> d[i];
        p[i]--;
        统一下标
            跑k次dfs,以i为起点,bfs,就知道各个点离i的距离,用距离来和d[i]比较,可以把不符合要求的点全部设为白。  但如果是求距离的话为什么不用最短路?
    bfs,一边处理,一边就可以判断点。
    最短路:
    跑完一遍最短路之后,要遍历其他点,判是否距离<d[i],好像也不是不行。
    不太知道bfs的前提,需要做做这个专题,就这题来看,因为要知道所有点到当前点的距离,所以挺适合bfs。
    ***
        vector<int> dis(N, -1);
        大小为N,初始值为-1
        queue<int> q;
        dis[p[i]] = 0;
        q.push(p[i]);
	        
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            
            if (dis[x] < d[i]) {
                black[x] = false;
            }
            for (auto y : adj[x]) {
                if (dis[y] == -1) {
                    dis[y] = dis[x] + 1;
	                    q.push(y);
                }
            }
        }
    }
    ***
        没搞懂为什么用bfs来搜,需要去做一下kuangbin搜索题
    似乎是因为要距离从小到大一层一层往外搜。
    
    bfs用于处理每条路径的距离,
    queue<int> q;
    vector<int> dis(N, -1);
    可以顺便初始化。
    for (int i = 0; i < N; i++) {
        if (black[i]) {
            q.push(i);
            dis[i] = 0;
        }
    }
    把可能的点推入。
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        
        for (auto y : adj[x]) {
            if (dis[y] == -1) {
                dis[y] = dis[x] + 1;
                q.push(y);
            }
        }
    }
    处理出每个黑点的最短距离
    ***
    for (int i = 0; i < K; i++) {
        if (dis[p[i]] != d[i]) {
            cout << "No\n";
            return 0;
        }
    }
        没有最短距离为d[i]的点
        

    cout << "Yes\n";
    for (int i = 0; i < N; i++) {
        cout << black[i];
    }
    cout << "\n";
    
    return 0;
}
模仿代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
int main(){
	int N,M;
	cin >> N >> M ;
	vector<vector<int> > adj(N);
	for(int i = 0;i < M;i++){
		int u,v;
		cin >> u >> v;
		u--,v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	vector<bool> black(N,1);
	int k;
	cin >> k;
	vector<int> p(k),d(k);
	for(int i = 0;i < k;i++){
		cin >> p[i] >> d[i];
		p[i] --;
		queue<int> q;
		vector<int> dis(N,-1);
		q.push(p[i]);
		dis[p[i]] = 0;
		while(q.size()){
			int x = q.front();
			q.pop();
			if(dis[x] < d[i]){
				black[x] = false;
			}
			for(auto y : adj[x]){
				if(dis[y] == -1){
					dis[y] = dis[x] + 1;
					q.push(y);
				}
			}
		}
	}
	queue<int> q;
	vector<int> dis(N,-1);
	for(int i = 0;i < N;i++){
		if(black[i]){
			q.push(i);
			dis[i] = 0;
		}
	}
	while(q.size()){
		int x = q.front();
		q.pop();
		for(auto y : adj[x]){
			if(dis[y] == -1){
				dis[y] = dis[x] + 1;
				q.push(y);
			}
		}
	}
	for(int i = 0;i < k;i++){
		if(dis[p[i]] != d[i]){
			cout << "No" << endl;
			return 0;
		}
	}
	cout << "Yes" << endl;
	for(int i = 0;i < N;i++){
		cout << black[i] ;
	}
	cout << "\n" ;
	return 0;
}


套路:

1)bfs无边权(权值为1)最短路

前提条件:求最短路,无边权图。
情景:

1)Catch That Cow

  • Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
  • Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
  • 每次移动,时间加一。时间也可以当作是一种距离。
    2)nearest Black Vertex
  • At least one vertex is painted black.
  • For every i=1,2,…,K, the following holds:
    • the minimum distance between vertex pi​ and a vertex painted black is exactly di​.
    • 把不符合要求的棋子标记为白,然后找出每个白棋子距离最近的黑棋子的距离。

都是需要找一个边权为1的图力点之间的最短距离。

应对:
1。求一个点到n个点的最短路:

把这个点当作起点。

2。 求1种点到距离另一种点的最短距离

把其中一种点全部推入循环,然后dis设置为0.n个起点。

关于为什么不用spfa,dijkstra

小贴士:
很多同学一看到「最短路径」,就条件反射地想到「Dijkstra 算法」。为什么 BFS 遍历也能找到最短路径呢?
这是因为,Dijkstra 算法解决的是带权最短路径问题,而我们这里关注的是无权最短路径问题。也可以看成每条边的权重都是 1。这样的最短路径问题,用 BFS 求解就行了。
在面试中,你可能更希望写 BFS 而不是 Dijkstra。毕竟,敢保证自己能写对 Dijkstra 算法的人不多。

总结:
bfs是处理无权边最短路的最优解。
spfa,dijkstra用来处理有权边
有边权最短路 --> dijkstra,spfa
无边权最短路 --> bfs
#bfs无边权最短路文章来源地址https://www.toymoban.com/news/detail-432849.html

到了这里,关于1262(构造)(bfs无边权最短路)(E - Nearest Black Vertex的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 迷宫问题:BFS(队列,最短路径)和DFS(栈

    搜索的基本算法分为两种:宽度优先搜索(Breadth-First Search,BFS)以及深度优先搜索(Depth-First Search,DFS)。 在学习过程中我们常常会遇到许多需要用搜索解决的问题。比如迷宫。 这次专题主要是对栈和队列的应用进行分析。所以首先我们先简要描述一下DFS和BFS方便大家对下

    2024年02月09日
    浏览(37)
  • 单源最短路(只有一个起点)bfs,多源BFS,目录力扣675.为高尔夫比赛砍树,多源最短路问题:力扣542.01矩阵力扣1020.飞地的数量

    目录 力扣675.为高尔夫比赛砍树 多源最短路问题: 力扣542.01矩阵 力扣1020.飞地的数量 Collections.sort(trees,(a,b)-{                    return f.get(a[0]).get(a[1])-f.get(b[0]).get(b[1]);                }); 这块比较难写 这段代码是Java中的一段代码,用于对名为trees的集合进行排序。这个集

    2024年04月12日
    浏览(67)
  • 【优选算法专栏】专题十六:BFS解决最短路问题---前言

    本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:算法从入门到精通 🚚代码仓库:小小unicorn的代码仓库

    2024年04月15日
    浏览(51)
  • 广度优先搜索(BFS)算法求解单源最短路径问题

      单源最短路径问题是图论中一类重要且常见的应用问题。在这个问题中,我们需要找到从一个给定源节点到其他节点的最短路径。广度优先搜索(BFS)算法是一种常用且有效的求解这一问题的算法。   本篇博客将重点讨论单源最短路径问题及其实际应用,同时简要介绍

    2024年02月13日
    浏览(47)
  • 详解图的最短路径算法(BFS、Dijkstra、Floyd)(附上图解步骤)

    最短路径分为两种: (1)单源路径:从某顶点出发,到其他全部顶点的最短路径 (2)顶点间的最短路径:任意两个顶点之间的最短路径 最短路径的结果主要有两个方面: (1)顶点之间最短路径的长度 (2)从源顶点到目标顶点的路径 只有边权为 1 时才能用BFS求最短路。

    2024年02月05日
    浏览(55)
  • 【每日一题Day218】LC1091 二进制矩阵中的最短路径 | BFS

    你驾驶出租车行驶在一条有 n 个地点的路上。这 n 个地点从近到远编号为 1 到 n ,你想要从 1 开到 n ,通过接乘客订单盈利。你只能沿着编号递增的方向前进,不能改变方向。 乘客信息用一个下标从 0 开始的二维数组 rides 表示,其中 rides[i] = [starti, endi, tipi] 表示第 i 位乘客

    2024年02月08日
    浏览(53)
  • 《图》经典题题解(拓扑排序,DFS,BFS,Floyd,Dijkstra,LCA最近公共祖先,最小生成树,最短路径)(ACM)

    目录 拓扑排序 / 家谱树 p1359租用潜艇 P1938[USACO09NOV] Job Hunt S  最短路计数 797. 所有可能的路径  200.岛屿数量 DFS BFS 695.岛屿的最大面积 DFS BFS P1119 灾后重建  P1629 邮递员送信 法一:Floyd 法二:Dijkstra P3379 【模板】最近公共祖先(LCA) 最小生成树 法一:prim算法 法二:Kruskal算

    2024年04月14日
    浏览(40)
  • 力扣日记1262

    LeetCode 1262. 可被三整除的最大和 数组中取数,使得和可以整出3且最大,每个数最多选一次 看数据量,复杂度可以到O(nlogn)往上 1 = nums.length = 4 * 10^4 1 = nums[i] = 10^4 思考一下怎么选数, 先想贪心。看出来这个题的答案是需要选数的组合,贪心不出来。 想动态规划。 对于下标

    2024年02月11日
    浏览(35)
  • 【1262. 可被三整除的最大和】

    来源:力扣(LeetCode) 描述: 给你一个整数数组 nums ,请你找出并返回能被三整除的元素最大和。 示例 1: 示例 2: 示例 3: 提示: 1 = nums.length = 4 * 10 4 1 = nums[i] = 10 4 方法:贪心 + 正向思维 我们把数组中的数分成三部分 a, b, c,它们分别包含所有被 3 除余 0 , 1, 2 的数。显

    2024年02月10日
    浏览(37)
  • LeetCode 1262. 可被三整除的最大和

    力扣题目链接:https://leetcode.cn/problems/greatest-sum-divisible-by-three/ 给你一个整数数组  nums ,请你找出并返回能被三整除的元素最大和。   示例 1: 示例 2: 示例 3:   提示: 1 = nums.length = 4 * 10^4 1 = nums[i] = 10^4 一个数对3取模,只有0、1、2这三种情况。 我们只需要对nums中所有数

    2024年02月09日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包