目录
- 图论复习
- 最小生成树
- 最短路
- tarjan再复习
- 树剖、树上差分、dfs序、LCT
- 割点
- 矩阵树定理和仙人掌、动态仙人掌
- 二分图匹配、网络流、费用流、上下界网络流
图论复习
(noip向
最小生成树
kruskal: 贪心,\(O(m\log m)\)
prim:稠密图可用 没用,复杂度\(O((n+m) \log (n+m))\)
斐波那契堆的prim在稠密图的时候是坠吼的,但是也没好到哪里去
最短路
SPFA判负环:一点出现次数>n
dijkstra求最短路:
while(!q.empty()){
if(q.top().w>dis[q.top().p]) continue;
int now=q.top().p;
for(int i=head[now];i;i=edge[i].nex){
int v=edge[i].v;
if(dis[v]>dis[now]+edge[i].w){
dis[v]=dis[now]+edge[i].w;
q.push(pt(v,dis[v]));
}
}
}
tarjan再复习
怎么老是记不住啊。。。
void dfs(int now){
dfn[now]=low[now]=++tot;
st[++tp]=now;
for(int i=head[now];i;i=edge[i].nex){
int v=edge[i].v;
if(!dfn[v]){
dfs(v);low[now]=min(low[v],low[now]);
}else if(!col[v]){
low[now]=min(low[v],low[now]);
}
}
if(low[now]==dfn[now]){
sz[++cn]=1;col[now]=cn;
while(st[tp]!=now){
sz[cn]++;col[st[tp--]]=cn;
}tp--;
}
}
int main(){
for(int i=1;i<=n;i++){
if(!dfn[i]) dfs(i);
}
}
缩点时注意需不需要去重
树剖、树上差分、dfs序、LCT
前三个都挺简单。。。主要是注意如何运用
LCT准备考后再复习,做题
割点
void dfs(int u,int rt) {
int pos=0;
dfn[u]=++cnt;
low[u]=cnt;
for(int i=head[u]; i; i=edge[i].nex) {
int v=edge[i].v;
if(!dfn[v]) {
if(u==rt) tot++;
dfs(v,rt);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=rt&&!pos){
pos=1;
ans[++num]=u;
}
} else low[u]=min(low[u],dfn[v]);
}
}
for(int i=1; i<=n; i++) {
if(!dfn[i]) {
tot=0;dfs(i,i);
if(tot>=2) ans[++num]=i; //特判搜索树的根
}
}
注意特判根节点
注意这里要这样写:low[u]=min(low[u],dfn[v]);
由于此处是一张无向图,我们有双向建了边,导致节点可以回溯到它的父节点;
而如果从它的父节点或其父节点的另一棵子树上有向上很多的返祖边,
这时把子节点的\(low\)值赋为父节点的\(low\),就可能导致其\(low=\)其父节点\(low<\)其父节点\(dfn\),
从而使本该是割点的点被忽视了,答案减少
矩阵树定理和仙人掌、动态仙人掌
noip不会考,不复习了(
二分图匹配、网络流、费用流、上下界网络流
同上