那么来一波模板吧=。=
来源:互联网 发布:充值系统源码 编辑:程序博客网 时间:2024/05/16 09:53
ST表(RMQ问题)
//打表与查询 这个是针对最大最小值
void STpre() { for(int i = 1; i <= n; i++) dp[i][0][0] = dp[i][0][1] = d[i]; for(int j = 1; (1<<j) < n; j++) for(int i = 1; i <= n; i++) { if(i + (1<<j) -1 > n) continue; dp[i][j][0] = max(dp[i][j-1][0],dp[i+(1<<(j-1))][j-1][0]); dp[i][j][1] = min(dp[i][j-1][1],dp[i+(1<<(j-1))][j-1][1]); } } void rmq(int a,int b) { int len = b-a+1; int k = 0; while(1<<(k+1) <= len) k++; int la = max(dp[a][k][0],dp[b-(1<<k)+1][k][0]); int sm = min(dp[a][k][1],dp[b-(1<<k)+1][k][1]); }
LCA(tarjan)
void tarjan(int u) { anc[u] = u; for(int i = h[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].to; if(!vis[v]) { vis[v] = 1; tarjan(v); join(u,v); anc[getf(u)] = u; vis[v] = 0; } } col[u] = 1; for(int i = h1[u]; ~i; i = query[i].next) { int v = query[i].to, id = query[i].w; if(!col[v]) continue; ans[id] = d[u] + d[v] - 2*d[anc[getf(v)]]; } }
LCA(倍增)
预处理每个结点的父亲和深度
void pre(int u,int d,int fa) //处理每个结点的深度和父亲 { for(int i = h[u]; ~i; i = edge[i].next) { int v = edge[i].to, w = edge[i].w; if(fa != v) { dis[v] = dis[u] + w; dp[v][0] = u; maxd[v] = d; pre(v,d+1,u); } } }
倍增的预处理
int doubl() //倍增的预处理 { for(int j = 1; j <= 20; j++) for(int i = 1; i <= n ; i++) { if((1 << j) > maxd[i]) continue; int k = dp[i][j-1]; dp[i][j] = dp[k][j-1]; } return 0; }
询问
int query(int a,int b) { int x = a, y = b; int ans = 0; if(maxd[x] > maxd[y]) swap(x,y); for(int j = 20; j >= 0; j--)//先跳到同一高度,再一起往上跳。 { if(maxd[x] == maxd[y]) break; if(maxd[y] - (1<<j) < maxd[x]) continue; ans += (dis[y] - dis[dp[y][j]]); y = dp[y][j]; } if(x == y) return ans; for(int j = 20; j >= 0; j--) { if(dp[x][0] == dp[y][0] )break; if(maxd[y] - (1 << j) < 0 || dp[x][j] == dp[y][j]) continue; ans += (dis[x]-dis[dp[x][j]] + dis[y] - dis[dp[y][j]]); x = dp[x][j], y = dp[y][j]; } ans += (dis[x] - dis[dp[x][0]] + dis[y] - dis[dp[y][0]]); return ans; }
tarjan
(1).求有向图强连通分量
int tarjan(int id){ vis[id] = 1; dfn[id] = low[id] = ++tot; sta[index++] = id; for(int i = head[id]; ~i; i = edge[i].next) { int v = edge[i].to; if(!dfn[v]) { tarjan(v); low[id] = min(low[id],low[v]); } else if(vis[v]) low[id] = min(low[id],dfn[v]); } if(low[id] == dfn[id]) { int num = 0; do { vis[sta[index--] ] = 0; num++; }while(sta[index] != id); ans[anum ++] = num; } return 0;}
(2).求无向图割点
void tarjan(int u,int father) { dfn[u] = low[u] = ++tot; int child = 0; for(int i = h[u]; ~i ; i = edge[i].next) { int v = edge[i].to; if(!dfn[v]) { child++; tarjan(v,u); low[u] = min(low[u],low[v]); if(low[v] >= dfn[u]) isCut[u] = 1; } else if(dfn[v] < dfn[u] && father != v) low[u] = min(low[u],dfn[v]); } if(father == -1 && child == 1) isCut[u] = 0; }
(3).求无向图割边(注意割边需要去重,也就是有重边的都不是割边)
int tarjan(int u,int fa){ dfn[u] = low[u] = ++tot; for(int i = h[u]; ~i; i = edge[i].next) { int v = edge[i].to; if(!dfn[v]) { tarjan(v,u); low[u] = min(low[u],low[v]); if(dfn[u] < low[v]) { int a = u, b = v; if(u > v) swap(a,b); edge[i].isb = 1; } } else if(dfn[v] < dfn[u] && v != fa) low[u] = min(low[u],dfn[v]); } return 0;}
匈牙利算法:
bool Find(int u) { for(int i = 1; i < rnum; i++) if(g[u][i] && !used[i]) { used[i] = 1; if(belong[i] == -1 || Find(belong[i])) { belong[i] = u; return true; } } return false; }
2-sat问题
缩点 + 拓扑序
void tarjan(int u) { low[u] = dfn[u] = ++tot; S[++snum] = u; inS[u] = 1; for(int i = h[u]; ~i; i = edge[i].next) { int v = edge[i].to; if(!dfn[v]) { tarjan(v); low[u] = min(low[u],low[v]); } else if(inS[v]) low[u] = min(low[u],dfn[v]); } if(low[u] == dfn[u]) { int v = -1; snum++; while(v != u) { v = S[snum--]; scc[v] = snum; inS[v] = 0; } } } void solve() { for(int i = 0; i < 2*n; i++) if(!dfn[i]) tarjan(i); int flag = 0; for(int i = 0; i < 2*n; i += 2) if(scc[i] == scc[i+1]) {flag = 1; break;} flag == 0 ? printf("YES\n") : printf("NO\n"); }
Dinic求最大流 前向弧优化+ 单路增广(因为多路我很迷茫)
bfs求层次图
int bfs(){ for(int i = s; i <= t; i++) deg[i] = -1; queue<int> q; q.push(s); deg[s] = 0; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = h[u]; ~i ; i = edge[i].next) { int v = edge[i].to,cap = edge[i].cap; if(cap && deg[v] == -1) { deg[v] = deg[u] + 1; q.push(v); } } } return deg[t] != -1;}
dfs找增广路
int dfs(int u,int f){ if(u == t) return f; for(int i = cur[u]; ~i; i = edge[i].next) { cur[u] = i; int v = edge[i].to, cap = edge[i].cap, rev = edge[i].rev; if(cap && deg[v] == deg[u] + 1) { int k = dfs(v,min(f,cap)); if(!k)continue; edge[i].cap -= k; edge[rev].cap += k; return k; } } return 0;}
void solve(){ int flow = 0; while(bfs()) { for(int i = s; i <= t; i++) cur[i] = h[i]; while(int k = dfs(s,inf)) flow += k; } cout << m-flow << endl;}
E-K + bellman
E-k算法其实就是找增广路的bfs实现,来达到每次都找的是最短增广路的目的。
对于最小费用最大流其实就是每次找费用最少且路径最短的增广路。
int bfs(){ for(int i = 0; i < maxn; i++) d[i] = inf,a[i] = 0,inq[i] = 0; queue<int> q; q.push(0); d[0] = 0;a[0] = inf; inq[0] = 1; while(!q.empty()) //找最短且费用最少的增广路 { int u = q.front(); q.pop(); inq[u] = 0; for(int i = h[u]; ~i; i = edge[i].next) { int v = edge[i].to,cap = edge[i].cap, w = edge[i].w; if(cap && d[v] > d[u] + w) { a[v] = min(a[u],cap); d[v] = d[u] + w; pre[v] = i; if(!inq[v]) {q.push(v); inq[v] = 1;} } } } if(d[t] == inf ) return 0; for(int u = t; u != st; u = edge[pre[u]].from) { int rev = edge[pre[u]].rev; edge[pre[u]].cap -= a[t]; edge[rev].cap += a[t]; } return d[t];}
阅读全文
0 0
- 那么来一波模板吧=。=
- 给你发那么, 不那么不那么,吧
- 那么就开始吧
- 那么这样的话,分吧?
- ABCD*9=DCBA 那么A=? B=? C=? D=?
- 1=5,2=15,3=215,4=2145,那么5=?
- ABCD×9=DCBA,那么A=?B=?C=?D=?
- android:showAsAction = "never"那么这句话是做什么用的呢
- 定义char dog[]="wang\0miao";那么sizeof(dog)与strlen(dog)分别是多少:
- 世界那么大,换一种生活吧!
- 我想说:工作没那么难找吧
- 那么近,那么远
- 支出,没那么,那么,
- 如果对象值相同(x.equals(y)==true),那么是否可以有不同的hash code?
- (转)B是A的子类,那么A a=new B();4不像的产生
- seq=1是收入,后面是支出,那么可以用case when把后面的数变为负数
- 游戏开发完要申请软件著作权,那么怎么写软件设计和使用说明呢?给出模板目录
- 那么小,那么慢,那么美
- Fragment回退栈管理
- 关于 bash:$'\r': command not found 的问题
- 个人博客的搭建
- ViewStub
- SSD5 数据结构 Course Design Exercise 3 解析
- 那么来一波模板吧=。=
- git添加到idea中流程
- Spring Boot系列教程七:Spring boot集成MyBatis
- css3 实现选项卡小三角形状
- junit 测试私有方法或私有变量
- webpack的使用-基础
- Java-集合之Map
- 九度OJ-题目1163:素数
- tensorflow使用tf.dynamic_rnn技巧