vis

CodeCraft-20 (Div. 2)

我只是一个虾纸丫 提交于 2020-03-05 07:08:47
D 被样例的构造误导到了奇怪的地方,以为“无限走”就要不断经过起始格子,实际上可以走到某个“核心”处然后在核心处绕圈圈。 int n; int x[1005][1005]; int y[1005][1005]; int vis[1005][1005]; int deg[1005][1005]; char ans[1005][1005]; int dx[4] = {0, 0, 1, -1}; int dy[4] = {-1, 1, 0, 0}; char dans[4] = {'R', 'L', 'U', 'D'}; char adans[4] = {'L', 'R', 'D', 'U'}; queue<pii> Q; void bfs1(int ux, int uy) { vis[ux][uy] = 1; ans[ux][uy] = 'X'; Q.push({ux, uy}); while(!Q.empty()) { int vx = Q.front().first; int vy = Q.front().second; Q.pop(); for(int i = 0; i < 4; ++i) { int tx = vx + dx[i]; int ty = vy + dy[i]; if(1 <= tx && tx <= n && 1 <= ty && ty <= n) { if(x

P3386 【模板】二分图匹配(匈牙利&最大流)

牧云@^-^@ 提交于 2020-03-05 06:01:26
P3386 【模板】二分图匹配 题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 输出格式: 共一行,二分图最大匹配 输入输出样例 输入样例#1: 复制 1 1 1 1 1 输出样例#1: 复制 1 说明 n,m \leq 1000 n , m ≤ 1 0 0 0 , 1 \leq u \leq n 1 ≤ u ≤ n , 1 \leq v \leq m 1 ≤ v ≤ m 因为数据有坑,可能会遇到 v>m v > m 的情况。请把 v>m v > m 的数据自觉过滤掉。 算法:二分图匹配 code 匈牙利 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 7 using namespace std; 8 9 const int N = 1010; 10 int e[N][N],vis[N],resut[N]; 11 int n,m,E; 12 13 inline int read() { 14 int x = 0,f = 1;char ch = getchar(); 15 for

[学习笔记]点分治

余生颓废 提交于 2020-03-04 15:12:34
点分治 解决问题 对于某些限定条件的路径静态地进行统计的算法. 基本思路 分治思想 对于某一点P,树上路径可以分为两类,经过点P,包含与点P的某一棵子树上 第二种可以递归处理 第一种通过求P的所有子节点的深度就可以处理 树的重心 如果是一条链的话,那复杂度很大,需要递归N层,每个节点访问一次. 用重心求只需要 \(log​\) 层  模板题① Tree 本题是求两点路径小于等于k code #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn = 1e4 + 7; const int inf = 0x3f3f3f3f; int k, tot, head[maxn]; bool vis[maxn]; int nowN, rt, maxP; int fin; int Size[maxn], dep[maxn]; struct Edge { int to, next, w; } e[maxn << 1]; vector<int> D; void init(int n) { tot = 0; for (int i = 0; i <= n; ++i) { head[i] = 0; vis[i] = 0; } fin = 0;

蓝桥杯 历届试题 合根植物java(dfs)

时光怂恿深爱的人放手 提交于 2020-03-04 14:14:51
问题描述   w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。   这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。   如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗? 输入格式   第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。   接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)   接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。   格子的编号一行一行,从上到下,从左到右编号。   比如:5 * 4 的小格子,编号:   1 2 3 4   5 6 7 8   9 10 11 12   13 14 15 16   17 18 19 20 样例输入 5 4 16 2 3 1 5 5 9 4 8 7 8 9 10 10 11 11 12 10 14 12 16 14 18 17 18 15 19 19 20 9 13 13 17 样例输出 5 样例说明   其合根情况参考下图 时间限制:2.0s 内存限制:256.0MB import java.beans.Visibility; import java.util.Scanner; public class

hdu 2066 ( 最短路) Floyd & Dijkstra & Spfa

风格不统一 提交于 2020-03-04 07:32:32
http://acm.hdu.edu.cn/showproblem.php?pid=2066 今天复习了一下最短路和最小生成树,发现居然闹了个大笑话-----我居然一直写的是Floyd,但我自己一直以为这是Dijkstra---我居然一直把两个算法 记的是混的,还居然一直没有被别人发现,真是个大乌龙 好了,看看这道题,赤裸裸的最短路水题,首先来个Floyd的,把城市看成点,将连通的的点赋值为给定的时间,未连通的赋值为很大,这是个无向的关系 然后就是三个循环,以一个点为媒介,把每个点遍历一遍,比较找出点连通的最小值就行,稍微优化一点点就不会超时了 code 1 #include<cstdio> 2 #include<algorithm> 3 #define inf 1000000005 4 using namespace std; 5 int mp[1001][1001],q[1001]; 6 void jjc() 7 { 8 int i,j; 9 for (i=1;i<=1000;i++){ 10 for (j=1;j<=1000;j++){ 11 if (i==j) mp[i][j]=0; 12 else mp[i][j]=inf; 13 } 14 } 15 } 16 int min(int x,int y){ 17 if (x<y) return x; 18 else

[2013 ACM/ICPC Asia Regional Hangzhou Online J/1010]hdu 4747 Mex (线段树)

烈酒焚心 提交于 2020-03-04 06:48:02
题意: 给定一个长度为 n 的非负数列,定义 mex(l, r) 为 l,r 区间里最小的没有出现的数字。 求所有 mex(l, r) 的和 分析参见 http://www.shuizilong.com/house/archives/hdu-4747-mex/ 我的代码: 1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <vector> 5 typedef long long ll; 6 #define lson l, mid, rt << 1 7 #define rson mid + 1, r, rt << 1 |1 8 9 struct node { 10 int mx, mi, setv; 11 ll sum; 12 }; 13 14 const int N = 200000 + 10 ; 15 int ar[N]; 16 node seg[N << 2 ]; 17 18 bool vis[N]; 19 int idx; 20 21 void Up(node& fa, node& ls, node& rs) { 22 fa.mx = std::max(ls.mx , rs.mx); 23 fa.sum = ls.sum + rs.sum; 24 fa.mi = std:

树边,前向边,后向边,横叉边

别来无恙 提交于 2020-03-03 21:37:47
原文地址: 树边,前向边,后向边,横叉边 树边,前向边,后向边,横叉边,应该说,不是一个图本身有的概念,应该是图进行DFS时才有的概念。图进行DFS会得到一棵DFS树(森林),在这个树上 才有了这些概念。对图进行DFS,可以从任意的顶点开始,遍历的方式也是多样的,所以不同的遍历会得到不同的DFS树,进而产生不同的树边,前向边,后向 边,横叉边。所以这4种边,是一个相对的概念。 在图的遍历中,往往设置了一个标记数组vis的bool值来记录顶点是否被访问过。但有些时候需要改变vis值的意义。令vis具有3种值并表示3种不同含义 vis = 0,表示该顶点没没有被访问 vis = 1,表示该顶点已经被访问,但其子孙后代还没被访问完,也就没从该点返回 vis = 2,,表示该顶点已经被访问,其子孙后代也已经访问完,也已经从该顶点返回 可以vis的3种值表示的是一种顺序关系和时间关系 《算法导论》334页有这4种边的准确定义,在此不累述 DFS过程中,对于一条边u->v vis[v] = 0,说明v还没被访问,v是首次被发现,u->v是一条树边 vis[v] = 1,说明v已经被访问,但其子孙后代还没有被访问完(正在访问中),而u又指向v?说明u就是v的子孙后代,u->v是一条后向边,因此后向边又称返祖边 vis[v] = 3,z说明v已经被访问,其子孙后代也已经全部访问完,u-

差分约束

烈酒焚心 提交于 2020-03-03 20:45:54
如果一个不等式组由 n 个变量和 m 个约束条件组成,形成 m 个形如x[ j ]-x[ i ]≤k(i,j∈[1,n] 且 k 为常数)的不等式,则称其为差分约束系统。换句话说,差分约束系统就是求解一组变量的不等式组的算法。 连边后求最短路 将x[ j ] ​ − x[ i ] ​ ≤ k 变形为 x[ j ] ​≤ k+ x[ i ] ​ ,即从 i 到j 连一条边权为 k 的边。加入超级源点后求最短路,得到 x i ​ ≤ 0 所有 x 最大解。 连边后求最长路 将 x[ j ] ​ − x[ i ] ​ ≤ k 变形为 x[ i ] ​ ≤ x[ j ]-k ​ ,即从 j 到 i 连一条边权为 − k 的边。加入超级源点后求最长路,得到 x i ​ ≥ 0 所有 x 最小解 1 #include<iostream> 2 #include<queue> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 #define N 5005 7 #define M 11000 8 int n,m,cnt; 9 int head[N]; 10 struct edge{ 11 int to,w,nxt; 12 }e[M]; 13 void add(int u,int v,int w){ 14 e[++cnt]

题解 P2661 【信息传递】

大憨熊 提交于 2020-03-03 07:25:52
这题 由于每个人只能告诉一个人,所以每个点的出度为1。找最小环。 坑点: 图不一定是连通图 故不能只用一遍bfs/dfs。 下面讲我的思路 三个数组 \(next,vis,dep\) ; \(next_i\) 记录第i位同学传递的人 \(vis_i\) 记录当前点是否访问和是哪一次访问 \(dep_i\) 记录第i个点在它的访问里的深度 当 \(dfs\) 时出现点已被访问,判断 是当前 \(dfs\) 访问过的点 \(then\) 更新答案 否则不考虑 #include <cstdio> using namespace std; int n,ans; int vis[200005],dep[200005],next[200005]; int main(){ ans=1<<17; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&next[i]); for(int i=1;i<=n;i++) if(vis[i]==0){ int dfs=0,j; for(j=i;vis[j]==0;j=next[j])vis[j]=i,dep[j]=++dfs; if(vis[j]==i && dfs-dep[j]<ans)ans=dfs-dep[j]; } printf("%d\n",ans+1); return 0; } 点个赞吧 来源:

P2414 [NOI2011]阿狸的打字机 · AC自动机 + fail树 + 树状数组

独自空忆成欢 提交于 2020-03-02 04:09:40
题解 学习来源1 · 大佬博客直通车 学习来源2 · 大佬博客直通车 学习来源3 · 大佬博客直通车 在ac自动机里, 如果字符串a可以通过fail指针指向字符串b,那么就说明a串中包含b串 问y串中有多少个x串,等同于问: y中有多少个节点的fail指针直接或间接指向x的末尾节点 可以看到主要是根据fail进行跳转, 建立ac自动机后,以fail的角度看,其构造形似是一颗树,建立起以fail为关系的树,现在我们把它就做fail树,其性质有: 一个字符串的后缀中有一个字符串等价fail树中一个节点的子树中有另一个节点 ,也就是看一个点在Trie中到根节点的路径上有多少个属于那个点的Fail树。 再看一遍题目,现在问题等价于: 统计x的子树中来自y的节点的个数, 而实际的答案就是 fail树上x串末尾点的子树与Trie树上x到y的树链的交集中点的个数 由于在一颗树中,一个节点及其子树在DFS序中是连续的一段 ,那么我们可以用一个 树状数组 来维护答案 所以,大致步骤如下: 根据ac自动机建立fail树, dfs求出每个串的起始位置和末尾位置,这将用于树状数组区间求和 保存每个问题对应的串和编号, 再跑一遍trie树,当遍历到代表y串的节点时,查询 tire树中 root - y 的路径上,有多少个节点属于fail树中x的子树 我终于会了… # include <bits/stdc++