Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_36480062
Algorithm
提交
c1210e3c
A
Algorithm
项目概览
qq_36480062
/
Algorithm
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
Algorithm
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
c1210e3c
编写于
8月 21, 2020
作者:
qq_36480062
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
c
上级
89c4564f
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
368 addition
and
13 deletion
+368
-13
ACWing/src/LCA/Tarjan求LCA.java
ACWing/src/LCA/Tarjan求LCA.java
+1
-1
ACWing/src/String/KMP.java
ACWing/src/String/KMP.java
+7
-9
ACWing/src/dp/单调队列dp/烽火传递.java
ACWing/src/dp/单调队列dp/烽火传递.java
+31
-0
ACWing/src/dp/单调队列dp/理想的正方形.java
ACWing/src/dp/单调队列dp/理想的正方形.java
+31
-3
ACWing/src/graph/AcWingEK.java
ACWing/src/graph/AcWingEK.java
+108
-0
ACWing/src/graph/EK.java
ACWing/src/graph/EK.java
+116
-0
ACWing/src/graph/有向图的强联通分量/受欢迎的牛.java
ACWing/src/graph/有向图的强联通分量/受欢迎的牛.java
+34
-0
ACWing/src/graph/有向图的强联通分量/强连通分量.md
ACWing/src/graph/有向图的强联通分量/强连通分量.md
+9
-0
ACWing/src/graph/洛谷二分图最大匹配.java
ACWing/src/graph/洛谷二分图最大匹配.java
+31
-0
未找到文件。
ACWing/src/LCA/Tarjan求LCA.java
浏览文件 @
c1210e3c
...
...
@@ -54,7 +54,7 @@ public class Tarjan求LCA {
}
for
(
int
i
=
0
;
i
<
m
;
i
++)
{
addq
(
nextInt
(),
nextInt
(),
i
);
}
}
//存储询问
tarjan
(
root
,
0
);
for
(
int
i
=
0
;
i
<
m
;
i
++)
{
bw
.
write
(
result
[
i
]
+
"\n"
);
...
...
ACWing/src/String/KMP.java
浏览文件 @
c1210e3c
...
...
@@ -5,6 +5,13 @@ import java.util.Scanner;
/**
* https://blog.csdn.net/qq_30277239/article/details/100881221
* 3
* aba
* 5
* ababa
* out:
* 0
* 2
*/
public
class
KMP
{
public
static
void
main
(
String
[]
args
)
{
...
...
@@ -46,13 +53,4 @@ public class KMP {
}
}
static
void
it
()
{
ne
[
0
]
=
-
1
;
int
t
=
0
;
for
(
int
i
=
1
;
i
<=
n
;
i
++)
{
t
=
ne
[
i
-
1
];
while
(
t
!=
-
1
&&
p
[
i
-
1
]
!=
p
[
t
])
t
=
ne
[
t
];
ne
[
i
]
=
t
+
1
;
}
}
}
ACWing/src/dp/单调队列dp/烽火传递.java
浏览文件 @
c1210e3c
...
...
@@ -7,11 +7,42 @@ import java.util.StringTokenizer;
import
static
java
.
lang
.
System
.
in
;
/**
* 烽火台是重要的军事防御设施,一般建在交通要道或险要处。
* 一旦有军情发生,则白天用浓烟,晚上有火光传递军情。
* 在某两个城市之间有 n 座烽火台,每个烽火台发出信号都有一定的代价。
* 为了使情报准确传递,在连续 m 个烽火台中至少要有一个发出信号。
* 现在输入 n,m和每个烽火台的代价,请计算在两城市之间准确传递情报所需花费的总代价最少为多少。
* 输入格式
* 第一行是两个整数 n,m,具体含义见题目描述;
* 第二行 n 个整数表示每个烽火台的代价 ai。
* 输出格式
* 输出仅一个整数,表示最小代价。
* 数据范围
* 1≤n,m≤2×10^5,
* 0≤ai≤1000
* 输入样例:
* 5 3
* 1 2 5 6 2
* 输出样例:
* 4
* https://blog.csdn.net/qq_30277239/article/details/104580927
* f[i]表示前1~i且点燃第i个烽火台,
* 属性:最小代价
* f[i]找倒数第2个, i-1 i-2...i-m+1 i-m
* f[i]=min(f[j] | i-m<=j<i )+w[i] 单调队列优化
* 本题属于单调队列优化DP的简单问题,
* 状态表示:f[i]表示前i个烽火台中第i个烽火台发出了信号的最少代价。
* 当然也可以使用状态机去解决,这里暂且用基本的线性DP的解法去解决,
* 则状态转移方程为f[i] = min(f[j]) + w[i],其中i - m <= j < i。
* 直接写时间复杂度是O(mn),显然会超时,由于f[i]最多仅用到了前面的m个状态,
* 所以可以使用单调队列优化,用单调队列求出区间长度是m的窗口中f的最小值。
* 单调队列的具体实现不再赘述,只需要注意两点即可。
* 第一点,连续m个烽火台中至少有一个要发出信号,需要仔细的理解这句话,
* 比如m = 3时,烽火台1 2 3 4 5 6,如果6发出信号,那么4 5 6这三个连续的烽火台就有了可以发出信号的烽火,
* 意味着上一个发出信号的最早可以是3,也就是枚举时i = 6,队头元素最小可以是3,
* 即i - q[hh] > m时才需要出队头,不需要加等号,这里容易出错。
* 第二点就是单调队列实现步骤中更新f[i]语句的位置,由于f[i]需要放进队列中,
* 所以需要先计算完f[i]才能够再与队尾元素比较来决定f[i]在队列中的最终位置。具体实现见代码:
*/
public
class
烽火传递
{
public
static
void
main
(
String
[]
args
)
throws
IOException
{
...
...
ACWing/src/dp/单调队列dp/理想的正方形.java
浏览文件 @
c1210e3c
...
...
@@ -28,6 +28,15 @@ import java.util.Scanner;
* 输出样例:
* 1
* 先预处理求每行的最值,在预处理列
* 先对矩阵逐行求区间长度是n的滑动窗口的最大最小值,分别存进最大最小值数组。
* 然后再对求出的最值数组按列再求一次最值,
* 二者之差就是所有n*n正方形区域内的最大整数与最小整数差了。当然,求滑动区间的最值就是使用单调队列实现的。
* 如图所示,如果要求3*3正方形中的最值,
* 可以先将各行中长度为3的区间的最值存在这个区间开始的格子里,比如上图蓝色的区域,
* 求完后,第一列的前三个格子就存了这个蓝色正方形各行的最值,
* 再竖着对第一行求下长度为3区间的最值存到第一个单元格里,第一个单元格存储的就是整个正方形区域内的最值了。
* 当然我们是先把初始矩形各行长度为n区间的最值存到一个新的数组,然后再对这个数组竖着求最值存入又一个数组来实现的,
* 以避免值被覆盖。实现细节见代码:
*/
public
class
理想的正方形
{
public
static
void
main
(
String
[]
args
)
{
...
...
@@ -41,14 +50,33 @@ public class 理想的正方形 {
}
}
for
(
int
i
=
1
;
i
<=
n
;
i
++)
{
getMin
(
w
[
i
],
row_min
[
i
],
m
);
getMax
(
w
[
i
],
row_max
[
i
],
m
);
}
int
[]
a
=
new
int
[
N
];
int
[]
b
=
new
int
[
N
];
int
[]
c
=
new
int
[
N
];
int
res
=
(
int
)
1
e9
;
for
(
int
i
=
k
;
i
<=
m
;
i
++)
{
for
(
int
j
=
1
;
j
<=
n
;
j
++)
{
a
[
j
]
=
row_min
[
j
][
i
];
}
getMin
(
a
,
b
,
n
);
for
(
int
j
=
1
;
j
<=
n
;
j
++)
{
a
[
j
]
=
row_max
[
j
][
i
];
}
getMax
(
a
,
c
,
n
);
for
(
int
j
=
k
;
j
<=
n
;
j
++)
{
res
=
Math
.
min
(
res
,
c
[
j
]
-
b
[
j
]);
}
}
System
.
out
.
println
(
res
);
}
static
void
getMin
(
int
[]
a
,
int
[]
b
,
int
tot
)
{
int
hh
=
0
,
tt
=
-
1
;
for
(
int
i
=
1
;
i
<=
tot
;
i
++)
{
if
(
hh
<=
tt
&&
q
[
hh
]
<=
i
-
tot
)
hh
++;
if
(
hh
<=
tt
&&
q
[
hh
]
<=
i
-
k
)
hh
++;
while
(
hh
<=
tt
&&
a
[
q
[
tt
]]
>=
a
[
i
])
tt
--;
q
[++
tt
]
=
i
;
b
[
i
]
=
a
[
q
[
hh
]];
...
...
@@ -58,7 +86,7 @@ public class 理想的正方形 {
static
void
getMax
(
int
[]
a
,
int
[]
b
,
int
tot
)
{
int
hh
=
0
,
tt
=
-
1
;
for
(
int
i
=
1
;
i
<=
tot
;
i
++)
{
if
(
hh
<=
tt
&&
q
[
hh
]
<=
i
-
tot
)
hh
++;
if
(
hh
<=
tt
&&
q
[
hh
]
<=
i
-
k
)
hh
++;
while
(
hh
<=
tt
&&
a
[
q
[
tt
]]
<=
a
[
i
])
tt
--;
q
[++
tt
]
=
i
;
b
[
i
]
=
a
[
q
[
hh
]];
...
...
ACWing/src/graph/AcWingEK.java
0 → 100644
浏览文件 @
c1210e3c
package
graph
;
import
java.io.*
;
import
java.util.ArrayDeque
;
import
java.util.Arrays
;
import
java.util.StringTokenizer
;
import
static
java
.
lang
.
System
.
in
;
public
class
AcWingEK
{
public
static
void
main
(
String
[]
args
)
throws
IOException
{
n
=
nextInt
();
m
=
nextInt
();
s
=
nextInt
();
t
=
nextInt
();
int
a
,
b
,
c
;
for
(
int
i
=
1
;
i
<=
m
;
i
++)
{
a
=
nextInt
();
b
=
nextInt
();
c
=
nextInt
();
add
(
a
,
b
,
c
);
}
System
.
out
.
println
(
ek
());
}
static
int
cnt
=
1
,
n
,
inf
=
(
int
)
1
e9
,
t
,
s
,
m
;
static
int
[]
h
=
new
int
[
1010
];
static
int
[]
e
=
new
int
[
20010
];
static
int
[]
ne
=
new
int
[
20010
];
static
int
[]
w
=
new
int
[
20010
];
static
boolean
[]
st
=
new
boolean
[
1202
];
static
int
[]
dis
=
new
int
[
1202
];
static
int
[]
pre
=
new
int
[
1010
];
//加双向边
static
void
add
(
int
a
,
int
b
,
int
c
)
{
e
[++
cnt
]
=
b
;
w
[
cnt
]
=
c
;
ne
[
cnt
]
=
h
[
a
];
h
[
a
]
=
cnt
;
e
[++
cnt
]
=
a
;
w
[
cnt
]
=
0
;
ne
[
cnt
]
=
h
[
b
];
h
[
b
]
=
cnt
;
}
static
ArrayDeque
<
Integer
>
q
=
new
ArrayDeque
<
Integer
>();
//使用bfs寻找增广路
static
boolean
bfs
()
{
Arrays
.
fill
(
st
,
false
);
q
.
clear
();
q
.
push
(
s
);
st
[
s
]
=
true
;
dis
[
s
]
=
inf
;
while
(!
q
.
isEmpty
())
{
int
x
=
q
.
pollFirst
();
for
(
int
i
=
h
[
x
];
i
!=
0
;
i
=
ne
[
i
])
{
int
v
=
e
[
i
];
if
(!
st
[
v
]
&&
w
[
i
]
!=
0
)
{
dis
[
v
]
=
Math
.
min
(
dis
[
x
],
w
[
i
]);
pre
[
v
]
=
i
;
q
.
push
(
v
);
st
[
v
]
=
true
;
if
(
v
==
t
)
return
true
;
}
}
}
return
false
;
}
static
int
ek
()
{
int
r
=
0
;
while
(
bfs
())
{
r
+=
dis
[
t
];
for
(
int
i
=
t
;
i
!=
s
;
i
=
e
[
pre
[
i
]
^
1
])
{
w
[
pre
[
i
]]
-=
dis
[
t
];
w
[
pre
[
i
]
^
1
]
+=
dis
[
t
];
}
}
return
r
;
}
static
BufferedWriter
bw
=
new
BufferedWriter
(
new
OutputStreamWriter
(
System
.
out
));
static
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
in
));
static
StringTokenizer
tokenizer
=
new
StringTokenizer
(
""
);
static
String
nextLine
()
throws
IOException
{
// 读取下一行字符串
return
reader
.
readLine
();
}
static
String
next
()
throws
IOException
{
// 读取下一个字符串
while
(!
tokenizer
.
hasMoreTokens
())
{
//如果没有字符了,就是下一个,使用空格拆分,
tokenizer
=
new
StringTokenizer
(
reader
.
readLine
());
}
return
tokenizer
.
nextToken
();
}
static
int
nextInt
()
throws
IOException
{
// 读取下一个int型数值
return
Integer
.
parseInt
(
next
());
}
static
double
nextDouble
()
throws
IOException
{
// 读取下一个double型数值
return
Double
.
parseDouble
(
next
());
}
}
ACWing/src/graph/EK.java
0 → 100644
浏览文件 @
c1210e3c
package
graph
;
import
java.io.*
;
import
java.util.ArrayDeque
;
import
java.util.Arrays
;
import
java.util.StringTokenizer
;
import
static
java
.
lang
.
System
.
in
;
public
class
EK
{
public
static
void
main
(
String
[]
args
)
throws
IOException
{
n
=
nextInt
();
m
=
nextInt
();
s
=
nextInt
();
t
=
nextInt
();
int
a
,
b
,
c
;
for
(
int
i
=
1
;
i
<=
m
;
i
++)
{
a
=
nextInt
();
b
=
nextInt
();
c
=
nextInt
();
if
(
flag
[
a
][
b
]
==
0
)
{
add
(
a
,
b
,
c
);
flag
[
a
][
b
]
=
cnt
;
}
else
{
w
[
flag
[
a
][
b
]
-
1
]
+=
c
;
}
}
while
(
bfs
())
{
update
();
}
System
.
out
.
println
(
ans
);
}
static
int
[][]
flag
=
new
int
[
1001
][
1001
];
static
int
cnt
=
1
,
n
,
inf
=
Integer
.
MAX_VALUE
/
2
,
t
,
s
,
ans
=
0
,
m
;
static
int
[]
h
=
new
int
[
1010
];
static
int
[]
e
=
new
int
[
20010
];
static
int
[]
ne
=
new
int
[
20010
];
static
int
[]
w
=
new
int
[
20010
];
static
boolean
[]
st
=
new
boolean
[
1002
];
static
int
[]
dis
=
new
int
[
1002
];
static
int
[]
pre
=
new
int
[
1010
];
//加双向边
static
void
add
(
int
a
,
int
b
,
int
c
)
{
e
[++
cnt
]=
b
;
w
[
cnt
]=
c
;
ne
[
cnt
]=
h
[
a
];
h
[
a
]=
cnt
;
e
[++
cnt
]=
a
;
w
[
cnt
]=
0
;
ne
[
cnt
]=
h
[
b
];
h
[
b
]=
cnt
;
}
static
ArrayDeque
<
Integer
>
q
=
new
ArrayDeque
<
Integer
>();
//使用bfs寻找增广路
static
boolean
bfs
()
{
Arrays
.
fill
(
st
,
false
);
q
.
clear
();
q
.
push
(
s
);
st
[
s
]
=
true
;
dis
[
s
]
=
inf
;
while
(!
q
.
isEmpty
())
{
int
x
=
q
.
pollFirst
();
for
(
int
i
=
h
[
x
];
i
!=
0
;
i
=
ne
[
i
])
{
if
(
w
[
i
]
==
0
)
continue
;
int
v
=
e
[
i
];
if
(
st
[
v
])
continue
;
dis
[
v
]
=
Math
.
min
(
dis
[
x
],
w
[
i
]);
pre
[
v
]
=
i
;
q
.
push
(
v
);
st
[
v
]
=
true
;
if
(
v
==
t
)
return
true
;
}
}
return
false
;
}
static
void
update
()
{
int
x
=
t
;
while
(
x
!=
s
)
{
int
v
=
pre
[
x
];
w
[
v
]
-=
dis
[
t
];
w
[
v
^
1
]
+=
dis
[
t
];
x
=
e
[
v
^
1
];
}
ans
+=
dis
[
t
];
}
static
BufferedWriter
bw
=
new
BufferedWriter
(
new
OutputStreamWriter
(
System
.
out
));
static
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
in
));
static
StringTokenizer
tokenizer
=
new
StringTokenizer
(
""
);
static
String
nextLine
()
throws
IOException
{
// 读取下一行字符串
return
reader
.
readLine
();
}
static
String
next
()
throws
IOException
{
// 读取下一个字符串
while
(!
tokenizer
.
hasMoreTokens
())
{
//如果没有字符了,就是下一个,使用空格拆分,
tokenizer
=
new
StringTokenizer
(
reader
.
readLine
());
}
return
tokenizer
.
nextToken
();
}
static
int
nextInt
()
throws
IOException
{
// 读取下一个int型数值
return
Integer
.
parseInt
(
next
());
}
static
double
nextDouble
()
throws
IOException
{
// 读取下一个double型数值
return
Double
.
parseDouble
(
next
());
}
}
ACWing/src/graph/有向图的强联通分量/受欢迎的牛.java
0 → 100644
浏览文件 @
c1210e3c
package
graph.
有向图的强联通分量
;
/**
*
*/
@SuppressWarnings
(
"all"
)
public
class
受欢迎的牛
{
public
static
void
main
(
String
[]
args
)
{
}
// static void tarjar(int u) {
// dfu[u] = low[u] = ++time;
// stk[++top] = u;
// in_stk[u] = true;
// for (int i = he[u]; i != 0; i = ne[i]) {
// int j=e[i];
// if (!dfn[j]){
// tarjar(j);
// low[u]=Math.min(low[u],low[j]);
// }else if (in_stk[j])
// low[u]=Math.min(low[u],dfn[j]);
// }
// if (dfn[u]==low[u]){
// int y;
// ++scc_cnt;
// do {
// y=stk[top--];
// in_stk[y]=false;
// id[y]=scc_cnt;
// }while (y!=u);
// }
// }
}
ACWing/src/graph/有向图的强联通分量/强连通分量.md
浏览文件 @
c1210e3c
...
...
@@ -13,3 +13,12 @@
后向边
横叉边
SCC强连通分量
1.某一点是否在强连通分量里面,存在后向边指向祖先节点,
2.先走到横叉边,横叉边再走到祖先节点
基于tarjan求强连通分量(SCC)
引入时间戳
dfn[u]遍历到u的时间
low[u]记录从u开始走,所能遍历到的最小时间戳是什么
u是其所在强连通分量的最高点,等价于dfn[u]==low[u]
ACWing/src/graph/洛谷二分图最大匹配.java
0 → 100644
浏览文件 @
c1210e3c
package
graph
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
import
java.util.StringTokenizer
;
/**
*
*/
public
class
洛谷二分图最大匹配
{
public
static
void
main
(
String
[]
args
)
{
}
static
int
n
,
m
,
N
=
510
,
M
=
5000
;
static
BufferedReader
br
=
new
BufferedReader
(
new
InputStreamReader
(
System
.
in
));
static
StringTokenizer
st
=
new
StringTokenizer
(
""
);
static
String
next
()
throws
IOException
{
while
(!
st
.
hasMoreTokens
())
{
st
=
new
StringTokenizer
(
br
.
readLine
());
}
return
st
.
nextToken
();
}
static
int
nextInt
()
throws
IOException
{
return
Integer
.
parseInt
(
next
());
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录