11.13
cin.getline(s,sizeof s,’\n’);
11.15 树
- 小球-drop
- 大事化小,n层化n-1层,计算进入该结点的次数
- 二叉树遍历-flist
- 中序+层序==前序
- 递归+按层遍历=前序遍历
- rank表,寻找最小结点
- 子树上结点号最小的结点是子树的根结点
- FBI树
- 同时进行递归计算FBI和后序遍历
- 猜数字
cout<<(min+max)/2<<endl;
- 人以群分
- 单调序列
- 最小环
- gcd多个最小环
- 物以类聚(如1、3、5、6、4、2)
11.17 树+堆
超级对拍程序
rem Name: Batch For Check
rem Copyright: All Right Reserved
rem Author: Chen Jie
rem Date: 2020/10/17
rem Description: RENAME the *.bat file and run it.
rem The batch will consider succesive spaces as one.
@echo off
::no parameter then begin for loop
if "%1"=="" goto loop
set BAT_NAME=%~nx0
::BAT_NAME=TFILE_NAME.bat
set FILE_NAME=%BAT_NAME:~0,-4%
::if no exist the corresponding input file, then end the batch
if not exist %FILE_NAME%%1.in (
goto end
)
if exist %FILE_NAME%%1.out (
set ANS_NAME=%FILE_NAME%%1.out
)
if exist %FILE_NAME%%1.ans (
set ANS_NAME=%FILE_NAME%%1.ans
)
copy %FILE_NAME%%1.in %FILE_NAME%.in >nul
echo Problem Test Data %1
time<enter
%FILE_NAME% < %FILE_NAME%.in > %FILE_NAME%.out
time<enter
::if exist error, then pause for showing the difference
fc %FILE_NAME%.out %ANS_NAME% /w /n
if errorlevel 1 (
pause>nul
)
del %FILE_NAME%.in
del %FILE_NAME%.out
::end the batch
goto end
:loop
::call the corresponding data batch
for %%i in (0 1 2 3 4 5 6 7 8 9 10 11) do call %0 %%i
echo Press Any Key To Exit ...
pause>nul
:end
就地建堆函数
- make_heap(),pop_heap(),push_heap()
C++中的make_heap(), pop_heap()的头文件为<algorithm>。作用与priority_queue<>;中的成员函数相同,可以单独使用。
在容器范围内,就地建堆,保证最大值在所给范围的最前面,其他值的位置不确定make_heap(begin,end,greater<int>());
将堆顶(所给范围的最前面)元素移动到所给范围的最后,并且将新的最大值置于所给范围的最前面pop_heap(begin,end,greater<int>());
当已建堆的容器范围内有新的元素插入末尾后,应当调用push_heap将该元素插入堆中。push_heap(begin,end,greater<int>());
code到word带格式复制
- 二叉树输出(btout)
- 一个数组能解决的事不要用结构体
- 查找二叉树(tree_a)
- 对称二叉树(tree_c)
- 合并果子(fruit)
11.18 堆+图
最小字典序Euler回路(逆序)
- 骑马修栅栏(fence)
void find(int now) { for (int k = mi; k <= ma; k++) if (available[now][k] > 0) { available[now][k]--; available[k][now]--; find(k); } c[++cnt] = now; }
命令参数
-
VS2019-项目-属性-调试-命令参数
- 命令行格式指定输入文件
< $(ProjectDir)$(Configuration)\$(ProjectName).in
- 命令行格式指定输入文件
-
基于红黑树的可重复集合
multiset<int>st; st.insert(a); cout << *st.begin() << ' '; st.erase(st.begin()); cout << *(--st.end()) << endl; st.erase(--st.end());
-
看病-hp
- release比debug快,约
4~6~9
倍 - 简单的程序倍数高
0.11-0.96 0.7-4 1.4-5.77
- release比debug快,约
-
小明的账单-bill
- heap不会错
- multiset太慢
-
铲雪车(snow)
- 加起来就好了,别多想
-
珍珠(bead)
- 不允许指向引用的指针、迭代器,即不允许定义
vector<typename&>vec;
- 不允许指向引用的指针、迭代器,即不允许定义
11.19 第三节 最短路径算法
F l o y e d Θ ( N 3 ) Floyed \Theta(N^3) FloyedΘ(N3)
- 适用于出现负边权的情况
初始化:点u、v如果有边相连,则dis[u][v]=w[u][v]。 如果不相连则dis[u][v]=INT_MAX
for (k = 1; k <= n; k++) for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) if (dis[i][j] > dis[i][k] + dis[k][j]) dis[i][j] = dis[i][k] + dis[k][j];
- 牛的旅行-travel
这两个牧场都在John的农场上。John将会在两个牧场中各选一个牧区,然后用一条路径连起来,使得连通后这个新的更大的牧场有最小的直径。注意,如果两条路径中途相交,我们不认为它们是连通的。只有两条路径在同一个牧区相交,我们才认为它们是连通的。 现在请你编程找出一条连接两个不同牧场的路径,使得连上这条路径后,这个更大的新牧场有最小的直径。 用Floyed求出任两点间的最短路,然后求出每个点到所有可达的点的最大距离,记做mdis[i]。(Floyed算法) r1=max(mdis[i]); 然后枚举不连通的两点i,j,把他们连通,则新的直径是mdis[i]+mdis[j]+(i,j)间的距离。 r2=min(mdis[i]+mdis[j]+dis[i,j]); re=max(r1,r2);//旧最大与新直径的最小的最大 re就是所求。
D i j k s t r a Θ ( N 2 ) Dijkstra \Theta(N^2) DijkstraΘ(N2)
- 不能处理存在负边权的情况
设起点为s,dis[v]表示从s到v的最短路径,pre[v]为v的前驱节点,用来输出路径。 a)初始化:dis[v]=∞(v≠s); dis[s]=0; pre[s]=0; b)For (i = 1; i <= n ; i++) 1.在没有被访问过的点中找一个顶点u使得dis[u]是最小的。 2.u标记为已确定最短路径 3.For与u相连的每个未确定最短路径的顶点v if (dis[u] + w[u][v] < dis[v]) { dis[v] = dis[u] + w[u][v]; pre[v] = u; } c)算法结束:dis[v]为s到v的最短距离;pre[v]为v的前驱节点,用来输出路径。
for (int i = 1; i <= n; ++i) { int k = 0; for (int j = 1; j <= n; ++j) if (!ok[j] && ans[j] < ans[k]) k = j; if (!k)break; ok[k] = true; for (int j = 1; j <= n; ++j) if (!ok[j] && ratio[j][k]) ans[j] = std::min(ans[j], ans[k] * ratio[j][k]); }
B e l l m a n − F o r d Θ ( N E ) Bellman-Ford \Theta(NE) Bellman−FordΘ(NE)
- 能够处理存在负边权的情况,但无法处理存在负权回路的情况
设s为起点,dis[v]即为s到v的最短距离,pre[v]为v前驱。w[j]是边j的长度,且j连接u、v。 初始化:dis[s]=0, dis[v]=∞(v≠s),pre[s]=0 For (i = 1; i <= n-1; i++) For (j = 1; j <= E; j++)//注意要枚举所有边,不能枚举点。 if (dis[u] + w[j] < dis[v])//u、v分别是这条边连接的两个点。 { dis[v] = dis[u] + w[j]; pre[v] = u; }
for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { dis[f[j].y] = std::min(dis[f[j].y], dis[f[j].x] + f[j].w); dis[f[j].x] = std::min(dis[f[j].x], dis[f[j].y] + f[j].w); }
S P F A Θ ( k E ) SPFA \Theta(kE) SPFAΘ(kE)
- B e l l m a n − F o r d Bellman-Ford Bellman−Ford算法的队列实现
-
k
k
k的平均值是2
dis[i]记录从起点s到i的最短路径,w[i][j]记录连接i,j的边的长度。pre[v]记录前趋。 team[1..n]为队列,头指针head,尾指针tail。 布尔数组exist[1..n]记录一个点是否现在存在在队列中。 初始化:dis[s]=0,dis[v]=∞(v≠s),memset(exist,false,sizeof(exist)); 起点入队team[1]=s; head=0; tail=1;exist[s]=true; do { 1、头指针向下移一位,取出指向的点u。 2、exist[u]=false;已被取出了队列 3、For与u相连的所有点v//注意不要去枚举所有点,用数组模拟邻接表存储 if (dis[v]>dis[u]+w[u][v]) { dis[v]=dis[u]+w[u][v]; pre[v]=u; if (!exist[v])//队列中不存在v点,v入队。 { //尾指针下移一位,v入队; exist[v]=true; } } } while (head < tail);
dis[i] = 0; team[0] = i; int head = 0, tail = 1; exist[i] = true; do { int u = team[head]; if (++head == 2 * 牧场)head = 0; exist[u] = false; for (int j = 1; j <= num[u]; ++j) { int v = a[u][j]; if (dis[v] > dis[u] + w[u][v]) { dis[v] = dis[u] + w[u][v]; if (!exist[v]) { team[tail] = v; if (++tail == 2 * 牧场)tail = 0; exist[v] = true; } } } } while (head != tail);
11.20
int a[5] = { 1,2,3,4,5 };
int* p = a;
&(p + 2);//“&”要求左值
&*(p + 2);//等于a + 2
11.21 第四节 图的连通性问题
一、判断图中的两点是否连通
- Floyed算法
- 时间复杂度: Θ ( N 3 ) \Theta(N^3) Θ(N3)
- 遍历算法
- 时间复杂度: Θ ( N 2 ) \Theta(N^2) Θ(N2)
二、最小环问题
最小环就是指在一张图中找出一个环,使得这个环上的各条边的权值之和最小。在Floyed的同时,可以顺便算出最小环。
记两点间的最短路为dis[i][j],g[i][j]为边<i,j>的权值。
for (k = 1; k <= n; k++)
{
for (i = 1; i <= k - 1; i++)
for (j = i + 1; j <= k - 1; j++)
answer = min(answer, dis[i][j] + g[j][k] + g[k][i]);
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}
answer即为这张图的最小环。
一个环中的最大结点为k(编号最大),与它相连的两个点为i,j,这个环的最短长度为g[i][k]+g[k][j]+(i到j的路径中,所有结点编号都小于k的最短路径长度)。
根据Floyed的原理,在最外层循环做了k-1次之后,dis[i][j]则代表了i到j的路径中,所有结点编号都小于k的最短路径。
综上所述,该算法一定能找到图中最小环。
三、求有向图的强连通分量
Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记。它的算法描述较为简单:
(1) 第一次对图G进行DFS遍历,并在遍历过程中,记录每一个点的退出顺序。
(2)倒转每一条边的方向,构造出一个反图G’。然后按照退出顺序的逆序对反图进行第二次DFS遍历。
每次遍历得到的那些点即属于同一个强连通分量。
QQ截图复制色号
- 按C复制色号dd,dd,dd,Ctrl+C复制16进制色号#hhhhhh
11.28
- &*=*&=
- 取地址运算符与解除引用运算符互逆
12.6
MyClass#1# MyFunc(MyClass#2# x)
{
cout << "MyFunc" << endl;
return x;
}
MyClass b = MyFunc(a);
- #2#不引用:先复制构造x,返回时根据#1#确定析构顺序
- #1#引用:先析构返回值(若需要),再复制构造b(局部变量无法传递)
- #1#不引用:先复制构造b,再析构返回值(若需要)
- 神奇的 Θ ( 1 ) \Theta(1) Θ(1)快速乘