Wrote out Centroid, Added to Custom_Cpp_STL

also added problem to func_graphs but it will probably be taken out as I am still unable to solve it even after being told solution
This commit is contained in:
Siyong 2020-07-19 00:43:55 -07:00
parent f2a6ac2409
commit 8851ff6a59
3 changed files with 115 additions and 16 deletions

View file

@ -5,7 +5,7 @@ author: Siyong Huang, Benjamin Qi
prerequisites:
- sorting-custom
- intro-ordered
description: "?"
description: "More ways to write custom comparators in C++ and incorporating them into STL objects."
frequency: 1
---
@ -43,7 +43,6 @@ int main() {
}
```
## Comparator
```cpp
@ -67,10 +66,20 @@ int main() {
}
```
<Info title="Pro Tip" >
You can also use the following syntax to declare set `v` using a function
`set<Edge,decltype(*cmp)> v(cmp);`
</Info>
Lambda expressions also work:
```cpp
auto cmp = [](const Edge& x, const Edge& y) { return x.w < y.w; };
//The real type of cmp is function<bool(const Edge&, const Edge&)>
//auto is used for short
int main() {
int M = 4;
@ -83,7 +92,13 @@ int main() {
}
```
In this case, we can shorten the declaration of `v` by writing `set<Edge,decltype(cmp)> v(cmp);` instead.
<Info title="Pro Tip" >
You can also use the following syntax to declare set `v` using a lambda
`set<Edge,decltype(cmp)> v(cmp);`
</Info>
## Functors
@ -127,9 +142,17 @@ int main() {
}
```
<Info title="Pro Tip">
One functor can be used for multiple objects. Just keep overloading the `()` operator!
</Info>
## Built-In Functors
Overloading the less than operator (`<`) automatically generates the functor `less<Edge>`. Similarly, overloading `>` automatically generates the functor [`greater<Edge>`](https://en.cppreference.com/w/cpp/utility/functional/greater). We can use this to store a set in reverse order.
Overloading the less than operator (`<`) automatically generates the functor [`less<Edge>`](https://en.cppreference.com/w/cpp/utility/functional/less).
Similarly, overloading (`>`) automatically generates the functor [`greater<Edge>`](https://en.cppreference.com/w/cpp/utility/functional/greater).
We can use this to store a set in reverse order.
```cpp
#include <bits/stdc++.h>
@ -166,4 +189,17 @@ The following are all valid:
set<int,greater<int>> a;
map<int,string,greater<int>> b;
priority_queue<int,vector<int>,greater<int>> c;
```
```
<Warning title="Priority Queues">
In C++, priority queues are sorted in decreasing order.
Specifically, larger elements have higher 'priority' and are popped first.
If you want smaller elements to be at the front of the queue, two ways are listed below
1. Overload the (`<`) operator to output the opposite effect.
2. Overload the (`>`) operator properly and use the (`greater<T>`) functor.
</Warning>

View file

@ -24,23 +24,29 @@ export const metadata = {
new Problem("POI", "Mafia", "https://szkopul.edu.pl/problemset/problem/w3YAoAT3ej27YeiaNWjK57_G/site/?key=statement", "Hard", false, ["Func Graph"], ""),
new Problem("POI", "Spies", "https://szkopul.edu.pl/problemset/problem/r6tMTfvQFPAEfQioYMCQndQe/site/?key=statement", "Hard", false, [], ""),
new Problem("POI", "Frog", "https://szkopul.edu.pl/problemset/problem/qDH9CkBHZKHY4vbKRBlXPrA7/site/?key=statement", "Hard", false, [], ""),
new Problem("ojuz", "Space Pirate", "JOI14_space_pirate", "Very Hard", false, ["Graphs"], "One of the most difficult problems of all time. Build a tree with a single back edge. Break into three cases: path -> other cycle, path -> subtree, path -> non-subtree. Then perform some black magic."),
],
}
};
## Functional Graphs
We'll consider graphs like the one presented in this problem:
<Problems problems={metadata.problems.sample} />
< br/>
Aka **successor graph**.
In a **functional graph**, each node has exactly one out-edge.
This is also commonly referred to as a **successor graph**.
### Resources
<Resources>
<Resource source="CPH" title="16.3, 16.4 - Successor Graphs"></Resource>
</Resources>
## Implementation
### Implementation
The following sample code counts the number of cycles in such a graph. The "stack" contains nodes that can reach the current node. If the current node points to a node `v` on the stack (`on_stack[v]` is true), then we know that a cycle has been created. However, if the current node points to a node `v` that has been previously visited but is not on the stack, then we know that the current chain of nodes points into a cycle that has already been considered.
@ -82,6 +88,14 @@ int main()
**Floyd's Algorithm**, also commonly referred to as the **Tortoise and Hare Algorithm**, is capable of detecting cycles in a functional graph in $O(N)$ time and $O(1)$ memory (not counting the graph itself)
### Resources
<Resources>
<Resource source="Medium" title="The Tortoise and the Hare (Floyd's Algorithm)" url="https://medium.com/@tuvo1106/the-tortoise-and-the-hare-floyds-algorithm-87badf5f7d41"></Resource>
</Resources>
### Implementation
```cpp
//UNTESTED
pair<int, int> detect_cycle(int *next, int start_node) //return pair(length of cycle, distance from start node to in cycle)
@ -105,12 +119,7 @@ pair<int, int> detect_cycle(int *next, int start_node) //return pair(length of c
}
```
<Resources>
<Resource source="Medium" title="The Tortoise and the Hare (Floyd's Algorithm)" url="https://medium.com/@tuvo1106/the-tortoise-and-the-hare-floyds-algorithm-87badf5f7d41"></Resource>
</Resources>
<IncompleteSection />
## Problems
### Problems
<Problems problems={metadata.problems.general} />

View file

@ -1,7 +1,7 @@
---
id: centroid
title: "Centroid Decomposition"
author: Benjamin Qi
author: Benjamin Qi, Siyong Huang
prerequisites:
- dfs
- SRQ
@ -14,12 +14,12 @@ import { Problem } from "../models";
export const metadata = {
problems: {
general: [
new Problem("CF", "Ciel the Commander", "problemset/problem/321/C", "Easy", false, ["Centroid"]),
new Problem("CF", "Ciel the Commander", "problemset/problem/321/C", "Easy", false, ["Centroid"], ""),
new Problem("CF", "Sherlock's bet to Moriarty", "contest/776/problem/F", "Normal", false, ["Centroid"], ""),
new Problem("CF", "Digit Tree", "contest/715/problem/C", "Normal", false, ["Centroid", "NT"], ""),
new Problem("CF", "Double Tree", "contest/1140/problem/G", "Normal", false, ["Centroid", "DP"], ""),
new Problem("ojuz", "JOI - Factories", "JOI14_factories", "Normal", false, ["Centroid"], ""),
new Problem("CF", "Sum of Prefix Sums", contest/1303/problem/G", "Hard", false, ["Centroid", "CHT"], ""),
new Problem("CF", "Sum of Prefix Sums", "contest/1303/problem/G", "Hard", false, ["Centroid", "CHT"], ""),
new Problem("YS", "Frequency Table of Tree Distance", "frequency_table_of_tree_distance", "Hard", false, ["Centroid", "FFT"], ""),
new Problem("DMOJ", "Bob Equilibrium", "dmopc19c7p6", "Hard", false, ["Centroid"], "tight time limit"),
new Problem("DMOJ", "Time Traveller Imaxblue", "tc19summerh", "Hard", false, ["Centroid"], ""),
@ -29,6 +29,12 @@ export const metadata = {
}
};
## Centroid Decomposition
**Centroid Decomposition** is a divide and conquer technique for trees.
The **centroid** of a tree is a node which, if rooted, results in no other nodes having a subtree of size greater than $\frac{N}{2}$.
**Centroid Decomposition** works by repeated splitting the tree and each of the resulting subgraphs at the centroid, producing $O(\log N)$ layers of subgraphs.
### Tutorial
<Resources>
@ -36,6 +42,54 @@ export const metadata = {
<Resource source="GFG" title="Centroid Decomposition of Tree" url="centroid-decomposition-of-tree"></Resource>
</Resources>
### Implementation
<LanguageSection>
<CPPSection>
<!-- pulled from https://codeforces.com/contest/1303/submission/76216413, which I think is my most recent centroid problem -->
```cpp
bool r[MN];//removed
int s[MN];//subtree size
int dfs(int n, int p = 0)
{
s[n] = 1;
for(int x : a[n])
if(x != p && !r[x])
s[n] += dfs(x, n);
return s[n];
}
int get_centroid(int n, int ms, int p = 0)//n = node, ms = size of tree, p = parent
{
for(int x : a[n])
if(x != p && !r[x])
if(s[x]*2 > ms)
return get_centroid(x, ms, n);
return n;
}
void centroid(int n = 1)
{
int C = get_centroid(n, dfs(n));
//do something
r[C] = 1;
for(int x : a[C])
if(!r[x])
centroid(x);
}
```
</CPPSection>
<JavaSection />
<PySection />
</LanguageSection>
### Problems
<Problems problems={metadata.problems.general} />