Skip to content

Commit

Permalink
3.5
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcxzyw committed Mar 5, 2019
1 parent 3f7005e commit 5f46656
Show file tree
Hide file tree
Showing 18 changed files with 1,146 additions and 25 deletions.
3 changes: 2 additions & 1 deletion OI-Source.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
"optional": "cpp",
"string_view": "cpp",
"cstddef": "cpp",
"queue": "cpp"
"queue": "cpp",
"filesystem": "cpp"
},
"latex-workshop.intellisense.citation.maxfilesizeMB": 128,
"latex-workshop.latex.recipes": [
Expand Down
24 changes: 15 additions & 9 deletions Queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- [ ] THUPC2017/2018
- [ ] 2017山东一轮集训
- [ ] THUSCH
- [ ] Hash Killer
# Min_25 筛
- [x] LOJ#6053. 简单的函数
- [ ] UOJ#188. 【UR #13】Sanrd
Expand Down Expand Up @@ -125,6 +126,8 @@
- [x] CF923E
- [ ] [清华集训2017] 生成树计数
- [ ] CF981H K Paths
- [ ] [CTSC2006]歌唱王国
- [ ] [CTSC2010]性能优化
# 后缀数组/后缀自动机/序列自动机
- [x] LOJ#111. 后缀排序
- [x] LOJ#2033. 「SDOI2016」生成魔咒
Expand Down Expand Up @@ -253,18 +256,19 @@
- [x] LOJ#2042. 「CQOI2016」不同的最小割
- [x] LOJ#2100. 「TJOI2015」线性代数
- [x] LOJ#6045. 「雅礼集训 2017 Day8」价
- [ ] LOJ#6511. 「雅礼集训 2018 Day8」B
- [x] LOJ#6511. 「雅礼集训 2018 Day8」B(乱搞)
- [ ] LOJ#6511. 「雅礼集训 2018 Day8」B(做完补充线性规划辅助网络流建图)
- [ ] LOJ#2146. 「SHOI2017」寿司餐厅
- [ ] CTSC2010
- [ ] [CTSC2010]星际旅行
- [ ] UOJ#UER8B
- [ ] POJ 2175 Evacuation Plan
- [ ] 方伯伯运椰子
- [ ] THUPC2017 Airport
- [ ] UOJ 无限之环
- [ ] CF739E
- [ ] 星际竞速
- [ ] LOJ#6014. 「网络流 24 题」最长 k 可重区间集
- [ ] LOJ#6008. 「网络流 24 题」餐巾计划(做完补技巧总结)
- [x] 方伯伯运椰子
- [ ] THUPC2017 Airport(题目不完整)
- [x] UOJ 无限之环
- [x] CF739E
- [x] 星际竞速
- [x] LOJ#6014. 「网络流 24 题」最长 k 可重区间集
- [x] LOJ#6008. 「网络流 24 题」餐巾计划(做完补技巧总结)
# 分块及按大小分类
- [x] LOJ#6277-6285
# 插头dp
Expand Down Expand Up @@ -401,3 +405,5 @@
- [ ] LOJ#2327. 「清华集训 2017」福若格斯
- [ ] LOJ#6033. 「雅礼集训 2017 Day2」棋盘游戏
- [ ] LOJ#6212. 「美团 CodeM 决赛」melon
# Delaunay三角剖分
- [ ] [ZJOI2018]保镖
22 changes: 19 additions & 3 deletions Review/NetworkFlows/Tricks.tex
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
\section{技巧总结}
\subsection{最大流}
\begin{itemize}
\item 若一个点只能被经过有限次,将其拆为入点和出点,入点到出点连流量为
经过次数限制的边。
\item 若一个点只能被经过有限次,将其拆为入点和出点,入点到出点连流量为经过次数限制的边。
\item 树形最大流可以贪心解决。
\item 将大于等于限制转化为恰好等于限制,由于最大流解决的限制是小于等于,当其满流时恰好
有解。
\item 构图使得满流时的解就是合法解。
\item 网格图若只需考虑相邻格子的影响,考虑黑白染色,然后建图
$S\rightarrow B\rightarrow W\rightarrow T$
\end{itemize}
\subsection{最小割}
\begin{itemize}
Expand All @@ -18,7 +22,19 @@ \subsection{费用流}
\item 若已知走一条边之前必定已经走完了另外几条边,则考虑动态加边。
\item 对于层数较少,结构简单的图,考虑使用其它数据结构贪心模拟费用流。
\item (待验证)判断一条边是否一定被选:在残量网络上跑SPFA,若距离差不等于边权则必选。
\item 餐巾计划问题:
\item 餐巾计划问题:一条脏餐巾被传递多次只能代表1的流量,会误导MCMF。考虑修改建图方式:
一条餐巾被使用一次必须要直接从S流到T,脏餐巾只能从S重新流出,由于每天会使用r条餐巾,再从
S免费补偿r条餐巾到表示当天将重复使用的脏餐巾的点(这一步尤为关键,注意题目是否有这个性质)。
简单地说,就是如果要一个物品经过一条路径需要消耗大于1的流量时,必须把每一段都拆成S-T的路径。

\CJKsout{2019.3.5:为什么我在LOJ上的餐巾计划和Luogu上的星际竞速代码都是rank2啊。。。}
\item 「雅礼集训 2018 Day8」B 乱搞:贪心策略是每次选取最长的路径优化,那么需要将时间
当做费用,每次优化都选取路径上的费用最小值,将其当做流量限制。剩下部分的证明留坑待补。
\index{*TODO!雅礼集训2018Day8B的乱搞做法证明}
\item Codeforces739E Gosha is hunting:两种精灵球混合使用会多计算$p_iu_i$的期望,
由于网络流并不支持流量缩放的功能,只能考虑最后减去这个值。那么精灵连两条边到汇点,一条
费用为0,另一条为$p_iu_i$。只使用一个精灵球时,MCMF将贪心选择费用为0的边。
简单地说,用流量和费用+贪心性质诱导MCMF。
\end{itemize}

上述内容参考了胡伯涛的2007年国家集训队论文《最小割模型在信息学竞赛中的应用》
Expand Down
4 changes: 4 additions & 0 deletions Review/Optmize/FP.tex
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,7 @@ \subsection{Dinkelbach法}
\end{itemize}

\CJKsout{2019.3.3:为什么又是rank2。。。}

{\bfseries 当无法求得最大值时,二分法比Dinkelbach法效率更高。而且Dinkelbach法可能
求出值恰好为0的解导致提前收敛,结果错误。这时可以给截距加上一个扰动,令其越过收敛点,
如果后续的解可行则继续迭代,即使不可行扰动也不会影响答案。}
2 changes: 0 additions & 2 deletions Review/Other/TricksAndIdeas.tex
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,6 @@ \subsection{注意事项/常见转化/思想}
\item 矩阵快速幂时若时间复杂度不优则观察矩阵的性质。
\item 与排序有关的问题:考虑枚举某个数$x$,将整个序列表示为01序列。序列在全局下有序,说明相邻的数
之间都是有序的。
\item 网格图若只需考虑相邻格子的影响,考虑黑白染色,然后建图
$S\rightarrow B\rightarrow W\rightarrow T$
\item 「HAOI2018」字串覆盖:根据数据范围提示讨论子串大小,不重复子串长则出现次数少,分两种情况使用
不同方法处理。「雅礼集训 2017 Day1」字符串:$k*q$小于等于定值$1e5$,并且当$k$较小与$q$较小时都有
较优的做法,分情况处理。一般来说,若存在两个量的乘积不超过定值,并且存在两种高效算法分别主要与这两个
Expand Down
135 changes: 135 additions & 0 deletions Source/DominatorTree/LOJ6511.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// ERROR
#include <algorithm>
#include <cstdio>
#include <vector>
const int size = 405, inf = 1 << 30;
struct G {
struct Edge {
int to, nxt;
} E[size];
int last[size], cnt;
G() : cnt(0) {}
void addEdge(int u, int v) {
++cnt;
E[cnt].to = v, E[cnt].nxt = last[u];
last[u] = cnt;
}
} A, B;
int p[size][6], d[size];
int lca(int u, int v) {
if(u == 0 || v == 0)
return u | v;
if(d[u] < d[v])
std::swap(u, v);
int delta = d[u] - d[v];
for(int i = 0; i < 6; ++i)
if(delta & (1 << i))
u = p[u][i];
if(u == v)
return u;
for(int i = 5; i >= 0; --i)
if(p[u][i] != p[v][i])
u = p[u][i], v = p[v][i];
return p[u][0];
}
int T[size], C[size], in[size], q[size], ans = 0;
struct Sol {
int lim, cw;
Sol(int lim, int cw) : lim(lim), cw(cw) {}
};
std::vector<Sol> DFS(int u, int t) {
ans = std::max(ans, t);
std::vector<Sol> cur;
for(int i = B.last[u]; i; i = B.E[i].nxt) {
int v = B.E[i].to;
std::vector<Sol> vres = DFS(v, t + T[v]);
if(i == B.last[u])
cur = vres;
else {
std::vector<Sol> mix;
for(int j = 0; j < cur.size(); ++j) {
Sol a = cur[j];
int minv = inf;
for(int k = 0; k < vres.size(); ++k)
if(vres[k].lim >= a.lim)
minv =
std::min(vres[k].cw, minv);
if(minv != inf) {
a.cw += minv;
mix.push_back(a);
}
}
for(int j = 0; j < vres.size(); ++j) {
Sol a = vres[j];
int minv = inf;
for(int k = 0; k < cur.size(); ++k)
if(cur[k].lim >= a.lim)
minv =
std::min(cur[k].cw, minv);
if(minv != inf) {
a.cw += minv;
mix.push_back(a);
}
}
cur.swap(mix);
}
}
Sol base(T[u], C[u]);
cur.erase(std::remove_if(cur.begin(), cur.end(),
[=](Sol sol) {
return sol.lim <=
base.lim &&
sol.cw >= base.cw;
}),
cur.end());
cur.push_back(base);
return cur;
}
int main() {
int n, m, w;
scanf("%d%d%d", &n, &m, &w);
for(int i = 1; i <= n; ++i)
scanf("%d", &T[i]);
for(int i = 1; i <= n; ++i)
scanf("%d", &C[i]);
for(int i = 1; i <= m; ++i) {
int u, v;
scanf("%d%d", &u, &v);
A.addEdge(u, v);
++in[v];
}
int rt = n + 1, qcnt = 0;
for(int i = 1; i <= n; ++i)
if(!in[i]) {
q[++qcnt] = i;
p[i][0] = rt;
d[i] = 1;
B.addEdge(rt, i);
}
for(int i = 1; i <= qcnt; ++i) {
int u = q[i];
for(int j = A.last[u]; j; j = A.E[j].nxt) {
int v = A.E[j].to;
p[v][0] = lca(p[v][0], u);
if(--in[v] == 0) {
B.addEdge(p[v][0], v);
for(int i = 1; i < 6; ++i)
p[v][i] = p[p[v][i - 1]][i - 1];
d[v] = d[p[v][0]] + 1;
q[++qcnt] = v;
}
}
}
for(int i = 1; i <= n; ++i)
printf("fa %d %d\n", i, p[i][0]);
std::vector<Sol> sols = DFS(rt, 0);
int res = 0;
for(int i = 0; i < sols.size(); ++i) {
Sol cs = sols[i];
if(cs.cw)
res = std::max(
res, std::min(cs.lim, w / cs.cw));
}
printf("%d\n", ans - res);
return 0;
}
4 changes: 2 additions & 2 deletions Source/Fractional Programming/3288.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ int main() {
int d = read();
if(u != S) {
if(c)
addEdge(v, u, a - d);
addEdge(u, v, b + d);
addEdge(u, v, a - d);
addEdge(v, u, b + d);
}
}
n += 2;
Expand Down
109 changes: 109 additions & 0 deletions Source/Fractional Programming/LOJ2214.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include <csetjmp>
#include <cstdio>
#include <cstring>
int read() {
int res = 0, c;
do
c = getchar();
while(c < '0' || c > '9');
while('0' <= c && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
return res;
}
const int size = 5005;
struct Edge {
int to, nxt, w;
} E[2 * size];
int last[size], cnt = 0;
void addEdge(int u, int v, int w) {
++cnt;
E[cnt].to = v, E[cnt].nxt = last[u], E[cnt].w = w;
last[u] = cnt;
}
typedef double FT;
const FT eps = 1e-3;
FT x, delta;
jmp_buf buf;
int vis[size];
FT dis[size];
void pre(int u, int d) {
vis[u] = d;
FT du = dis[u];
for(int i = last[u]; i; i = E[i].nxt) {
int v = E[i].to;
FT dv = du + E[i].w + x;
if(dv < dis[v]) {
if(vis[v]) {
delta =
(dis[v] - dv) / (d + 1 - vis[v]);
longjmp(buf, 1);
}
dis[v] = dv;
pre(v, d + 1);
break;
}
}
vis[u] = 0;
}
int D;
void DFS(int u, int d) {
if(d == D)
return;
vis[u] = d;
FT du = dis[u];
for(int i = last[u]; i; i = E[i].nxt) {
int v = E[i].to;
FT dv = du + E[i].w + x;
if(dv < dis[v]) {
if(vis[v]) {
delta =
(dis[v] - dv) / (d + 1 - vis[v]);
longjmp(buf, 1);
}
dis[v] = dv;
DFS(v, d + 1);
}
}
vis[u] = 0;
}
bool iter(int n) {
memset(dis + 1, 0, sizeof(double) * n);
memset(vis + 1, 0, sizeof(int) * n);
if(setjmp(buf)) {
x += delta + 1e-4;
return delta > eps;
} else {
for(int i = 1; i <= n; ++i)
pre(i, 1);
int end = n * 2;
for(D = 1; D <= end; ++D)
for(int i = 1; i <= n; ++i)
DFS(i, 1);
return false;
}
}
int main() {
int n = read();
int m = read();
int S = n + 1;
for(int i = 1; i <= m; ++i) {
int u = read();
int v = read();
int a = read();
int b = read();
int c = read();
int d = read();
if(u != S) {
if(c)
addEdge(u, v, a - d);
addEdge(v, u, b + d);
}
}
x = 0.0;
while(iter(n + 2))
;
printf("%.2lf\n", x);
return 0;
}
Loading

0 comments on commit 5f46656

Please sign in to comment.