dfs

HDU5692 Snacks DFS序 线段树

狂风中的少年 提交于 2020-01-20 06:59:48
去博客园看该题解 题目 HDU5692 Snacks Problem Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通。每个零食机都有一个值v,表示为小度熊提供零食的价值。 由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。 为小度熊规划一个路线,使得路线上的价值总和最大。 Input 输入数据第一行是一个整数T(T≤10),表示有T组测试数据。 对于每组数据,包含两个整数n,m(1≤n,m≤100000),表示有n个零食机,m次操作。 接下来n−1行,每行两个整数x和y(0≤x,y<n),表示编号为x的零食机与编号为y的零食机相连。 接下来一行由n个数组成,表示从编号为0到编号为n−1的零食机的初始价值v(|v|<100000)。 接下来m行,有两种操作:0 x y,表示编号为x的零食机的价值变为y;1 x,表示询问从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。 本题可能栈溢出,辛苦同学们提交语言选择c++,并在代码的第一行加上: `#pragma comment(linker, "/STACK:1024000000,1024000000") ` Output 对于每组数据

[置顶] 树链剖分小节

自作多情 提交于 2020-01-20 00:38:10
前段时间学习了下树链剖分,好久没看了,今天又复习一遍,赶紧写下来,别又忘了。 我们在信息学竞赛中,有时会碰到这么一类题型,在一棵树中,修改两点之间路径上的所有边(或点)上的某个变量(如边的长度,点的权值等等),然后询问单个点(或边)或者两点之间路径上的所有点(或边)的某些性质(如边权之和,最大边最小边等等)。对于这样的题,往往容易往线段树上去靠,但是,单单是用线段树是无法维护每一条链的性质的,所以我们需要一种算法将树链分开来,使得每条链可以和线段树中的一个区间一一对应上。(当然树链剖分远远不止这些简单的应用,也不一定要和线段树有什么关系,总之就是将树链剖分开来吧)。 树链剖分有很多种剖分方法,最常用的应该就是轻重边剖分了吧(在网上大部分介绍的都是这种剖分方法),什么是轻重边剖分呢? 我们首先将树中的边分为两部分,轻边和重边,记size(U)为以U为根的子树的节点的个数,令V为U的儿子中size最大的一个(如有多个最大,只取一个),则我们说边(U,V)为重边,其余的边为轻边(如下图所示红色为重边,蓝色为轻边)。 我们将一棵树的所有边按上述方法分成轻边和重边后,我们可以得到以下几个性质: 1:若(U,V)为轻边,则size(V)<=size(U)/2。 这是显然的。 2:从根到某一点的路径上轻边的个数不会超过O(logN),(N为节点总数)。 这也是很简单

数据结构与算法(bfs与dfs)

旧街凉风 提交于 2020-01-20 00:08:58
引言 :经过上一次的学习,我们明白了图的基本操作。这一次,我们学习图的两种基本算法——bfs与dfs。 图(二) 图的遍历 1.dfs算法 (一)dfs模板 (二)例题 2.bfs算法 (一)bfs模板 (二)例题 后记 图的遍历 1.dfs算法 介绍:dfs算法也叫深度优先搜索,核心思想是从某一位置或者状态出发,进行搜索,直到找到为止。形象的可以认为是所有的可能都走一边,既暴力。 深度优先遍历图的方法是,从图中某顶点v出发: (1)访问顶点v; (2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问; (3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。 (一)dfs模板 void dfs ( 写入的参数 ) { if ( 条件符合要求 ) { 进行相关的操作(比如输出,计数等) return ; //结束操作 } 循环遍历每一种可能,进行相关的操作 { if ( 这种方式没有进行 ) { 标记 ; 进行 ; dfs ( 参数改变 ) ; 回溯 ; } } } (二)例题 下面给出一道相关的例题: 排列数字 给定一个整数n,将数字1~n排成一排,将会有很多种排列方法。 现在,请你按照字典序将所有的排列方法输出。 Input 共一行,包含一个整数n。 Output

数位dp (2)

有些话、适合烂在心里 提交于 2020-01-19 23:48:16
今天继续写几个数位dp F - Balanced Number 题目大意:给你一个区间,让你求这个区间之中满足条件的数字有多少。 这个条件:可以选数的一个位为轴,左右到轴的长度乘上那个数字本身相等的数有多少? 我的思路:首先我们要研究这个题目的数字要求,就是找到一个点然后去枚举每一个点是轴,然后我们就再dfs里面搜索 因为我们要求点到轴的力矩,但是我们又不知道力矩的位置,所以我们用一个数来记录到此位置的力矩 这个怎么记录呢?比如说数字abcdef 第一次就是a,第二次是a*2+b 第三次是a*3+b*2+c。。。。 所以我们需要有一个来记录这个力矩,还需要有一个数来记录 a a+b a+b+c.... 这个时候就很好求了。 所以这个dp我是这么定义的 dp[i][j][k][h]表示到第 i 位 轴为 j 力矩为 k 数字之和为 h 但是自己敲了之后发现有问题 首先就是这个数组开的太大了,其次就是这个状态定义的唯一不唯一很难确定。 我对于这个dp数组是真的无奈,不知道该怎么去定义,有时候定义多了,有时候定义少了。 状态是不是唯一真的很难去判断。 看了题解,题解是这么定义的, dp[i][j][k] 表示第 i 为以第 j 位 是否满足条件,满足k==0,不满足k!=0 这个状态一定义下来,就很好写这个dp了。 !!注意最后要减去全为0 的数,0 00 000 0000 000000

SSL的LeetCode初步刷题记

岁酱吖の 提交于 2020-01-19 13:53:13
岛屿数量 是否独立完成:否 答案出处:题解 思路:首先遍历数组 当某个数组值为“1”,则表明找到一个岛或者一个岛的一部分了,接着我们需要知道该元素的上下左右,是否也都为“1”,于是我们要访问该元素的上下左右的元素,同理,我们也要对该元素的上下左右元素,做与之前相同的事。 当某个数组值为“0”,直接跳过下一个。 注意不要碰到数组的边界 class Solution { public void dfs ( char [ ] [ ] grid , int r , int c ) { int nr = grid . length ; int nc = grid [ 0 ] . length ; if ( r < 0 || c < 0 || r >= nr || c >= nc || grid [ r ] [ c ] == '0' ) return ; //排除四种情况,则退出,r和c显然不能小于0,这是左边界, //再者r和c显然,不能大于等于他们的自己的最大值,这是右边界 grid [ r ] [ c ] = '0' ; //走过的岛,全部置位0,表明已经访问过。 dfs ( grid , r - 1 , c ) ; dfs ( grid , r + 1 , c ) ; dfs ( grid , r , c + 1 ) ; dfs ( grid , r , c - 1 ) ; }

N皇后问题

我怕爱的太早我们不能终老 提交于 2020-01-18 22:30:27
排序+打表 代码入下: #include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> using namespace std; // 棋盘 答案 int chess[12], s[12]; int ans, n; void dfs(int k)//设置第k行,即前k-1行已经设置好了 { if(k == n){//到头了,说明此路走得通,计数器+1 ++ans; return; } for (int i = 0; i < n;i++){ int j; for (j = 0; j < k;j++){ if(i == chess[j]||(k-j) == abs(i-chess[j]))//不能吃到 break; } if(j == k) {//满足条件,则设置下一行 chess[k] = i; dfs(k + 1); } } } int main() { //打表 for (int i = 1; i <= 10;++i){ //初始化 ans = 0; n = i; memset(chess, 0, 12); dfs(0); s[i] = ans; } while (cin >> n) { if (!n) break; cout << s[n] << endl;//取数 } return 0;

BFS和队列

非 Y 不嫁゛ 提交于 2020-01-18 22:17:05
   深度优先搜索(DFS) 和 广度优先搜索(BFS) 是基本的暴力技术,常用于解决图、树的遍历问题。   首先考虑算法思路。以老鼠走迷宫为例:   (1):一只老鼠走迷宫。它在每个路口都选择先走右边,直到碰壁无法继续前进,然后回退一步,这一次走左边,接着继续往下走。用这个办法能走遍 所有 的路,而且 不会重复 。这个思路就是DFS。   (2):一群老鼠走迷宫。假设老鼠是无限多的,这群老鼠进去后,在每个路口派出部分老鼠探索没有走过的路。走某条路的老鼠,如果碰壁无法前进,就停下;如果到达的路口已经有其他的老鼠探索过了,也停下。很显然, 所有 的道路都会走到,而且 不会重复 。这个思路就是BFS。       A - Red and Black   There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles. Write a program

P1141 01迷宫 题解 DFSorBFS

拟墨画扇 提交于 2020-01-18 19:13:49
这道题虽然在BFS的练习范围 但是我看到这道题第一个念头是用dfs写 不过我自己写的dfs tle了 然后参(模)考(仿)了题解里的一个dfs思路终于过了 下面放上参考的思路博客地址: 思路参考博客 DFS代码: # include <bits/stdc++.h> using namespace std ; int n , m ; int dx [ 4 ] = { 0 , - 1 , 0 , 1 } , dy [ 4 ] = { - 1 , 0 , 1 , 0 } ; int a [ 1010 ] [ 1010 ] , vis [ 1010 ] [ 1010 ] , ans [ 1000000 ] ; struct Node { int x , y , a , i ; Node ( int _x , int _y , int _a , int _i ) { //构造函数 x = _x , y = _y , a = _a , i = _i ; } } ; void dfs ( Node t ) { if ( vis [ t . x ] [ t . y ] || t . x <= 0 || t . x > n || t . y <= 0 || t . y > n || a [ t . x ] [ t . y ] != t . a ) //剪枝 return ; vis [ t . x

Lake Counting//POJ - 2386//dfs

一曲冷凌霜 提交于 2020-01-18 09:52:58
Lake Counting//POJ - 2386//dfs 题目 Due to recent rains, water has pooled in various places in Farmer John’s field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water (‘W’) or dry land (’.’). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors. Given a diagram of Farmer John’s field, determine how many ponds he has. Input Line 1: Two space-separated integers: N and M Lines 2…N+1:

leetcode[130] Surrounded Regions

此生再无相见时 提交于 2020-01-17 04:09:34
给定一个类似棋盘,有X和O,把X圈住的O变为X例如: For example, X X X X X O O X X X O X X O X X After running your function, the board should be: X X X X X X X X X X X X X O X X 其实这题的思路,就是先找到四周的O,然后和四周的O相邻的O全都是不可能转化为X的,我们用另外一个符号标记,那么最后,矩阵中的O就是被圈住的,就需要转化为X,然后其他标记的符号就要转为原来的O。这个叫做DFS。 class Solution { public: void dfs(vector<vector<char> > &board, int x, int y) { if(x<0 || x>=board.size() || y<0 || y>=board[0].size() || board[x][y]!='O') return; board[x][y]='#'; dfs(board, x-1,y); dfs(board, x+1,y); dfs(board, x,y-1); dfs(board, x,y+1); } void solve(vector<vector<char> > &board) { if (board.size() < 3) return ; if