# codeBook
``` c++
#include <sstream>
getline(cin, str);
stringstream ss;
ss << str;
vector<int> p;
while (ss >> m) p.push_back(m);
```
``` c++
#include<iomanip>
cout << setw(4) << output;
```
``` c++
#include <iostream>
#include <vector>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
return 0;
}
```
priority_queue:優先隊列,資料預設由大到小排序,即優先權高的資料會先被取出。
宣告:
priority_queue <int> pq;
把元素 x 加進 priority_queue:
pq.push(x);
讀取優先權最高的值:
x = pq.top();
pq.pop(); // 讀取後刪除
pq.empty() 回傳true
pq.size() 回傳零
如需改變priority_queue的優先權定義:
* priority_queue<T> pq; 預設由大排到小
* priority_queue<T, vector<T>, greater<T> > pq; 改成由小排到大
* priority_queue<T, vector<T>, cmp> pq; 自行定義 cmp 排序
ZzKKu3
LCS
``` c++
vector<vector<int> >dp(str1.length() + 1, vector<int>(str2.length() + 1, 0));
for(int i = 1; i <= str1.length(); i++) {
for(int j = 1; j <= str2.length(); j++) {
if(str1[i - 1] == str2[j - 1]) {
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j - 1] + 1);
} else {
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
}
}
}
for(int i = 1; i <= str1.length(); i++) {
for(int j = 1; j <= str2.length(); j++) {
cout << dp[i][j] << " ";
}
cout << endl;
}
```
Greedy
``` c++
vector<vector<int> > dp(n, vector<int>(n, 0));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(j - i == 2)
dp[i][j] = v[j - 2] * v[j - 1] * v[j];
if(j - i > 2)
dp[i][j] = INT32_MAX;
}
}
for(int i = n - 1; i >= 0; i--) {
for(int j = 0; j < n; j++) {
for(int k = i + 1; k < j; k++) {
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] +v[i] * v[j] * v[k]);
}
}
}
```
``` c++
sort(v.begin(), v.end());
for(int i = 1; i <= k; i++) {
for(int j = 1; j <= n; j++) {
int z;
for(z = 1; z < j; z++) {
if(v[j] - v[z] <= 5)
break;
}
dp[i][j] = max(dp[i][j - 1], dp[i - 1][z - 1] + (j - z + 1));
}
}
```
無限背包
``` c++
sort()
for(int i = 1; i < dp.size(); i++) {
dp[i] = unit * i;
for(int j = 0; j < v.size(); j++) {
if(v[j].first > i)
break;
dp[i] = min(dp[i - v[j].first] + v[j].second, dp[i]);
}
```
01 背包
``` c++
for( int i = 1 ; i <= n; i++ ){
for( int j = 1 ; j <= num ; j++ ){
if( v[j] <= i ) dp[i][j] = max( dp[i-v[j]][j-1]+v[j], dp[i][j-1] );
else dp[i][j] = dp[i][j-1];
}
}
```
``` c++
vector<long long> dp(3, 0);
long long best = 0;
for(int i = 0; i < n; i++) {
cin >> v[i];
// (沒乘 + 有乘 or 有乘 + 有乘 or 新的有乘 在加沒乘) or 新的沒乘
dp[2] = max(dp[1] + v[i], max(dp[2] + v[i], v[i]));
// 沒乘 + 有乘 or 有乘 + 有乘 or 新的有乘
dp[1] = max(dp[0] + x * v[i], max(dp[1] + x * v[i], x * v[i]));
// 沒乘 + 沒乘 or 新的沒乘
dp[0] = max(dp[0] + v[i], v[i]);
best = max(best, max(dp[2], max(dp[1], dp[0])));
}
```
``` c++
void pull(int x) {
total[x] = total[x << 1] + total[x << 1|1];
}
void build(int x, int l, int r) {
if(l == r) {
total[x] = 1;
return;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1|1, mid + 1, r);
pull(x);
}
int query(int x, int l, int r, int ql, int qr) {
if(ql <= l && qr >= r)
return total[x];
int ret = 0;
int mid = (l + r) >> 1;
if(ql <= mid) {
ret += query(x<<1, l, mid, ql, qr);
}
if(qr > mid) {
ret += query(x<<1|1, mid + 1, r, ql, qr);
}
return ret;
}
void update(int x, int l, int r, int pos, int val){
if (l == r){
total[x] = val;
return;
}
int mid = (l+r) >> 1;
if (pos <= mid) update(x<<1, l, mid, pos, val);
else update(x<<1|1, mid+1, r, pos, val);
pull(x);
}
int main() {
build(1, 1, 8);
update(1, 1, 8, 8, 2);
for(int i = 0; i < 30; i++) {
cout << total[i] << " ";
}
}
```
```
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<queue>
using namespace std;
int day, n, k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> day >> n >> k;
long long max = 0;
vector<vector<long long>> v(day + 2, vector<long long>(3, 0));
for(int i = 0; i < n; i++) {
int c, b, e;
cin >> c >> b >> e;
for(int j = b; j <= e; j++) {
if(v[j][0] == k) {
if(v[j][1] < c) {
v[j][2] -= v[j][1];
v[j][2] += c;
v[j][1] = c;
}
} else {
if(v[j][1] > c || v[j][0] == 0) {
v[j][1] = c;
}
v[j][2] += c;
v[j][0] ++;
}
max = v[j][2] > max ? v[j][2] : max;
}
}
cout << max;
}
```
## Graph
### DFS
1. Tree edge:若vertex(Y)是被vertex(X)「發現」,則edge(X,Y)即為Tree edge,也就是Depth-First Tree中的edge。
透過顏色判斷edge:當vertex(X)搜尋到vertex(Y),且vertex(Y)為「白色」時,就會建立出Tree edge。
2. Back edge:所有指向ancestor的edge,稱為Back edge。如圖六中,edge(F,B)與edge(H,G)。
透過顏色判斷edge:當vertex(X)搜尋到vertex(Y),且vertex(Y)為「灰色」,就會建立起Back edge,見圖三(j)、圖三(q)與圖六。
3. Forward edge:所有指向descendant但不是Tree edge的edge,稱為Forward edge。觀察「時間軸」,若Graph存在例如:edge(A,D)、edge(A,E)或者edge(B,E),即可稱之為Forward edge。很遺憾的,圖六中,沒有Forward edge。
透過顏色判斷edge:當vertex(X)搜尋到vertex(Y)時,vertex(Y)為「黑色」,並且discover[X]<discover[Y],edge(X,Y)即為Forward edge。
4. Cross edge:若兩個vertex 不在同一棵Depth-First Tree上,例如vertex(C)與vertex(H),或者兩個vertex在同一棵Depth-First Tree上卻沒有「ancestor-descendant」的關係,例如vertex(C)與vertex(F),則稱連結此兩個vertex的edge為Cross edge。
透過顏色判斷edge:當vertex(X)搜尋到vertex(Y)時,vertex(Y)為「黑色」,並且discover[X]>discover[Y],edge(X,Y)即為Cross edge。
``` c
void DFS(int vertex, int &time, vector<vector<int> > &adj, vector<int> &discover, vector<int> &color, vector<int> &finish, vector<queue <int> > &q){
if(color[vertex] == 2)
return;
if(color[vertex] == 0) {
color[vertex] = 1;
discover[vertex] = time;
time ++;
for(int i = 0; i < 8; i++) {
if(adj[vertex][i] && color[i] == 0){
q[vertex].push(i);
}
}
while(!q[vertex].empty()) {
int cur = q[vertex].front();
q[vertex].pop();
DFS(cur, time, adj, discover, color, finish, q);
}
}
if(color[vertex] == 1) {
color[vertex] = 2;
finish[vertex] = time;
time ++;
}
}
```
### Bellman-Ford
```c
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define P pair<long long, int>
int main() {
vector<P> G[5];
G[0].push_back(P(3, 4));
G[0].push_back(P(10, 1));
G[1].push_back(P(4, 4));
G[1].push_back(P(2, 2));
G[2].push_back(P(9, 3));
G[3].push_back(P(7, 2));
G[4].push_back(P(1, 1));
G[4].push_back(P(8, 2));
G[4].push_back(P(2, 3));
long long dist[5];
for(int i = 0; i < 5; i++) {
dist[i] = 1000000;
}
dist[0] = 0;
for(int j = 0; j < 5; j++){
for(int i = 0; i < 5; i++){
for (auto nxt: G[i]){
if (dist[nxt.second] > dist[i] + nxt.first){
dist[nxt.second] = dist[i] + nxt.first;
}
}
for(int i = 0; i < 5; i++) {
cout << dist[i] << " ";
}
cout << endl;
}
}
}
```
### DijkstraAlgorithm
``` c
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define P pair<long long, int>
int main() {
vector<P> G[5];
G[0].push_back(P(3, 4));
G[0].push_back(P(10, 1));
G[1].push_back(P(4, 4));
G[1].push_back(P(2, 2));
G[2].push_back(P(9, 3));
G[3].push_back(P(7, 2));
G[4].push_back(P(1, 1));
G[4].push_back(P(8, 2));
G[4].push_back(P(2, 3));
priority_queue<P, vector<P>, greater<P> > pq;
long long dist[5];
for(int i = 0; i < 5; i++) {
dist[i] = 1000000;
}
dist[0] = 0;
pq.push(P(0, 0));
while (!pq.empty()){
P p = pq.top();
pq.pop();
for (auto nxt: G[p.second]){
if (dist[p.second] < p.first) continue;
if (dist[nxt.second] > dist[p.second] + nxt.first){
dist[nxt.second] = dist[p.second] + nxt.first;
pq.push(P(dist[nxt.second], nxt.second));
}
}
for(int i = 0; i < 5; i++) {
cout << dist[i] << " ";
}
cout << endl;
}
}
```
### Floyd–WarshallAlgorithm
``` c
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define P pair<long long, int>
int main() {
vector<vector<int> > G;
G.push_back(vector<int>{0, 2, 6, 4});
G.push_back(vector<int>{1000000, 0, 3, 1000000});
G.push_back(vector<int>{7, 1000000, 0, 1});
G.push_back(vector<int>{5, 1000000, 12, 0});
for(int k = 0; k < 4; k++) {
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(G[i][j] > G[i][k] + G[k][j]) {
G[i][j] = G[i][k] + G[k][j];
}
}
}
}
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
cout << G[i][j] << " ";
}
cout << endl;
}
}
```
### Kruskal'sAlgorithm
``` c
#include<iostream>
#include<vector>
#include<algorithm>
#include<tuple>
using namespace std;
class DSU
{
int *parent;
int *rank;
public:
DSU(int n)
{
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++)
{
parent[i] = -1;
rank[i] = 1;
}
}
// Find function
int find(int i)
{
if (parent[i] == -1)
return i;
return parent[i] = find(parent[i]);
}
// union function
void unite(int x, int y)
{
int s1 = find(x);
int s2 = find(y);
if (s1 != s2)
{
if (rank[s1] < rank[s2])
{
parent[s1] = s2;
rank[s2] += rank[s1];
}
else
{
parent[s2] = s1;
rank[s1] += rank[s2];
}
}
}
};
class Graph
{
vector<tuple<int, int, int>> edgelist;
int V;
public:
Graph(int V)
{
this->V = V;
}
void addEdge(int x, int y, int w)
{
edgelist.push_back({w, x, y});
}
int kruskals_mst()
{
// 1. Sort all edges
sort(edgelist.begin(), edgelist.end());
// Initialize the DSU
DSU s(V);
int ans = 0;
for (auto edge : edgelist)
{
int w = get<0>(edge);
int x = get<1>(edge);
int y = get<2>(edge);
// take that edge in MST if it does form a cycle
if (s.find(x) != s.find(y))
{
s.unite(x, y);
ans += w;
}
}
return ans;
}
};
int main()
{
int n, m;
cin >> n >> m;
Graph g(n);
for (int i = 0; i < m; i++)
{
int x, y, w;
cin >> w >> x >> y;
g.addEdge(x, y, w);
}
cout << g.kruskals_mst();
return 0;
}
```
#### Version 2
``` c
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class DSU
{
int *parent;
int *rank;
public:
DSU(int n)
{
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++)
{
parent[i] = -1;
rank[i] = 1;
}
}
// Find function
int find(int i)
{
if (parent[i] == -1)
return i;
return parent[i] = find(parent[i]);
}
// union function
void unite(int x, int y)
{
int s1 = find(x);
int s2 = find(y);
if (s1 != s2)
{
if (rank[s1] < rank[s2])
{
parent[s1] = s2;
rank[s2] += rank[s1];
}
else
{
parent[s2] = s1;
rank[s1] += rank[s2];
}
}
}
};
class Graph
{
vector<vector<int>> edgelist;
int V;
public:
Graph(int V)
{
this->V = V;
}
void addEdge(int x, int y, int w)
{
edgelist.push_back({w, x, y});
}
int kruskals_mst()
{
// 1. Sort all edges
sort(edgelist.begin(), edgelist.end());
// Initialize the DSU
DSU s(V);
int ans = 0;
for (auto edge : edgelist)
{
int w = edge[0];
int x = edge[1];
int y = edge[2];
// take that edge in MST if it does form a cycle
if (s.find(x) != s.find(y))
{
s.unite(x, y);
ans += w;
}
}
return ans;
}
};
int main()
{
int n, m;
cin >> n >> m;
Graph g(n);
for (int i = 0; i < m; i++)
{
int x, y, w;
cin >> w >> x >> y;
g.addEdge(x, y, w);
}
cout << g.kruskals_mst();
return 0;
}
```
## maxFlow
add_edge 要從 bgm->add_edge(from, to, cap)
```c=
#include<iostream>
#include<vector>
#include<queue>
#include<memory.h>
#define MAXN 1000
#define INF 10
using namespace std;
typedef struct MaxFlow mf;
struct MaxFlow{
struct edge{
int to, cap, flow, rev;
};
vector<edge> v[MAXN];
int s, t, dis[MAXN], cur[MAXN];
int dfs(int u, int cap){
if(u == t || !cap)
return cap;
for(int &i = cur[u]; i < v[u].size(); i++){
edge &e = v[u][i];
if(dis[e.to] == dis[u] + 1 && e.flow != e.cap){
int df = dfs(e.to, min(e.cap - e.flow, cap));
if(df){
e.flow += df;
v[e.to][e.rev].flow -= df;
return df;
}
}
}
dis[u] = -1;
return 0;
}
bool bfs(){
memset(dis, -1, sizeof(dis));
queue<int> q;
q.push(s), dis[s] = 0;
while(!q.empty()){
int tmp = q.front();
q.pop();
for(auto &u : v[tmp]){
if(!~dis[u.to] && u.flow != u.cap){
q.push(u.to);
dis[u.to] = dis[tmp] + 1;
}
}
}
return dis[t] != -1;
}
int maxflow(int _s, int _t){
s = _s, t = _t;
int flow = 0, df;
while(bfs()){
memset(cur, 0, sizeof(cur));
df = dfs(s, INF);
while(df){
flow += df;
df = dfs(s, INF);
}
}
return flow;
}
void addedge(int st, int ed, int cap){
v[st].push_back(edge{ed, cap, 0, (int)v[ed].size()});
v[ed].push_back(edge{st, 0, 0, (int)v[st].size() - 1});
}
};
int main() {
mf *maxF = new MaxFlow();
maxF->addedge(0, 1, 2);
maxF->addedge(1, 2, 2);
maxF->addedge(2, 3, 2);
maxF->addedge(0, 4, 3);
maxF->addedge(4, 5, 3);
maxF->addedge(5, 3, 3);
maxF->addedge(3, 4, 2);
cout << maxF->maxflow(0, 3) << endl;
}
```
## matching
add_edge 要從 bgm->add_edge(小, 大)
```c=
#include<iostream>
#include<vector>
#include<bitset>
#include<memory.h>
#define MAXN 1000
using namespace std;
typedef struct Bipartite_Graph_Matching BGM;
struct Bipartite_Graph_Matching{
int mp[MAXN + 1], mq[MAXN + 1], n;
bitset<MAXN + 1> vis;
vector<int> child[MAXN + 1];
void init(int _n){
n = _n;
for(int i = 1; i <= n; i++)
child[i].clear();
}
void add_edge(int x, int y){
child[x].push_back(y);
}
bool dfs(int x){
vis[x] = 1;
for(int i : child[x])
if(!~mq[i] || !vis[mq[i]] && dfs(mq[i]))
return mq[mp[x] = i] = x, 1;
return 0;
}
int matching(){
int ans = 0;
memset(mp, -1, sizeof(mp)), memset(mq, -1, sizeof(mq));
for(int i = 1; i <= n; i++)
if(vis.reset(), dfs(i))
ans++;
return ans;
}
};
int main() {
BGM *bgm = new BGM();
bgm->init(6);
bgm->add_edge(1, 4);
// bgm->add_edge(1, 5);
// bgm->add_edge(1, 6);
bgm->add_edge(2, 4);
bgm->add_edge(2, 5);
// bgm->add_edge(2, 6);
bgm->add_edge(3, 4);
bgm->add_edge(3, 5);
bgm->add_edge(3, 6);
cout << bgm->matching();
}
```