再补一下
树上差分:
点差分:路径u->v上加x
w[u]+=x,w[v]+=x,w[LCA(u,v)]-= x ,w[fa[LCA(u,v)]]-=x
边差分:同上:
w[u]+=x,w[v]+=x,w[LCA(u,v)]-=2*x
关于粗体的部分,可以自己模拟一下
有关连通性:
用途:随机图->缩点->DAG图->方便处理
tarjan算法(yxc建议背模板)
有向图强连通tarjan:
void tarjan(int u) { low[u]=dfn[u]=++totn; sta[++tail]=u; instack[u]=1; for(int it=head[u];~it;it=nxt[it]) { int to=e[it]; if(dfn[to]) { if(instack[to]) low[u]=min(low[u],low[to]); } else{ tarjan(to); low[u]=min(low[u],low[to]); } } if(low[u]==dfn[u]) { ids++; while(sta[tail]!=u) { siz[ids]++; int top=sta[tail]; tail--; id[top]=ids; instack[top]=0; } int top=sta[tail]; siz[ids]++; tail--; id[top]=ids; instack[top]=0; } }
无向图双连通:
void tarjan(int u,int from) { low[u]=dfn[u]=++cnt; sta[++tail]=u; for(int it=head[u];~it;it=nxt[it]) { int to=e[it]; if(!dfn[to]) { tarjan(to,it); low[u]=min(low[u],low[to]); if(dfn[u]<low[to]) { is_bridge[it]=is_bridge[it^1]=1; } } else { if(it!=(from^1)) { low[u]=min(low[u],dfn[to]); } } } if(dfn[u]==low[u]) { int top; ids++; while(sta[tail]!=u) { top=sta[tail--]; id[top]=ids; } top=sta[tail--]; id[top]=ids; } }
二分图:
最小点覆盖点数=最大边匹配边数
最大独立点集点数= 总点数 -最小点覆盖点数
DAG最小路径点覆盖=二分图上:(二分图最大独立点集点数)
(证明太麻烦了,大概知道怎么回事就行)
欧拉回路、路径:
无向图:回路:当所有点的度都为偶数时,从任一点出发,可以回到此点
路径:存在回路,或者正好有2个点度数为奇数,从一个奇数点出发,回到另一个奇数点
有向图:回路:当所有点入度=出度
路径:存在回路,或者正好有一个点(入=出+1)并且正好有另一个点(出=入+1)
topsort:
得到一个DAG的拓扑序,然后就可以按照顺序进行DP、递推,求解某值