【模板】其他图论
来源:互联网 发布:java分解质因数 编辑:程序博客网 时间:2024/06/05 20:29
LCA(暴力):
#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int MAXN = 50000 + 50;int n, tot = 0, m;int first[MAXN], nxt[MAXN << 1], dis[MAXN], deep[MAXN], fa[MAXN];bool vis[MAXN];struct edge{ int from, to, cost;}es[MAXN << 1];void build(int ff, int tt, int dd){ es[++tot] = (edge){ff,tt,dd}; nxt[tot] = first[ff]; first[ff] = tot;}void dfs(int x){ for(int i = first[x]; i != -1; i = nxt[i]) { int v = es[i].to; if(!vis[v]) { vis[v] = 1; dis[v] = es[i].cost; deep[v] = deep[x] + 1; fa[v] = x; dfs(v); } }}int lca(int x, int y){ int ans = 0; if(deep[x] > deep[y]) swap(x,y); while(deep[y] != deep[x]) { ans += dis[y]; y = fa[y]; } while(x != y) { ans += dis[x]; ans += dis[y]; x = fa[x]; y = fa[y]; } return ans;}int main(){ scanf("%d",&n); memset(first,-1,sizeof(first)); memset(dis,0x3f3f3f3f,sizeof(dis)); for(int i = 1; i < n; i ++) { fa[i] = i; int f, t, d; scanf("%d%d%d", &f, &t, &d); build(f,t,d); build(t,f,d); } deep[0] = 1; vis[0] = 1; dfs(0); scanf("%d",&m); while(m --) { scanf("%d%d", &f, &t); printf("%d\n",lca(f,t)); } return 0;}
LCA(倍增):
#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>using namespace std;const int SZ = 501000;struct edge{ int f,t;}es[SZ<<1];int tot = 0,first[SZ<<1],nxt[SZ<<1];int deep[SZ],anc[SZ][30];bool vis[SZ];void build(int f,int t){ es[++tot] = (edge){f,t}; nxt[tot] = first[f]; first[f] = tot;}void dfs(int u){ vis[u] = 1; if(u == 0) deep[u] = 1; for(int i = 1;i <= 16;i ++) anc[u][i] = anc[anc[u][i-1]][i-1]; for(int i = first[u];i;i = nxt[i]) { int v = es[i].t; if(!vis[v]) { anc[v][0] = u; deep[v] = deep[u] + 1; dfs(v); } }}int lca(int u,int v){ if(deep[u] < deep[v]) swap(u,v); int tt = deep[u]-deep[v]; for(int i = 0;i <= 16;i ++) { if(tt & (1 << i)) u = anc[u][i]; } for(int i = 16;i >= 0;i --) if(anc[u][i] != anc[v][i]) { u = anc[u][i]; v = anc[v][i]; } if(u != v) return anc[u][0]; return u;}int main(){ int n,m,s; scanf("%d%d%d",&n,&m,&s); for(int i = 1;i < n;i ++) { int u,v; scanf("%d%d",&u,&v); build(u,v); build(v,u); } dfs(s); for(int i = 1;i <= m;i ++) { int u,v; scanf("%d%d",&u,&v); printf("%d\n",lca(u,v)); } return 0;}
Tarjan:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<stack>using namespace std;const int maxn=100010;int scc[maxn],dfn[maxn];//强连通分量、第一次发现 int low[maxn];//某点及其后代能连到的最早值 int head[maxn],tot,cnt,ans[maxn];//scc总数 和 访问次数stack<int>s;struct Edge{ int to; int fff; int d; int next;}edge[maxn];void build(int fff,int tt) { edge[++tot].to=tt; edge[tot].next=head[fff]; head[fff]=tot;}int dfs_clock=0;void tarjan(int u){ dfn[u]=low[u]=++dfs_clock; s.push(u); for(int i=head[u];i;i=edge[i].next) { Edge e=edge[i]; int v=e.to; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(!scc[v]) { low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]) { cnt++; while(1) { int x=s.top(); s.pop(); scc[x] = cnt; ans[scc[x]] = cnt2; if(x == u)break; } }}
SPFA判负环:
ll spfa(ll s){ memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(use,0,sizeof(use)); dis[s] = 0; q.push(s); vis[s] = 1; use[s] = true; while(!q.empty()) { ll u = q.front(); q.pop(); use[u] = false; if(vis[u] > n + 1) return -1; for(ll i = first[u];i != -1;i = next[i]) { ll v = l[i].t; if(dis[v] > dis[u] + l[i].v) { dis[v] = dis[u] + l[i].v; vis[v] = vis[u] + 1; if(!use[v]) { q.push(v); use[v] = true; } } } } return 0;}int main(){ init(); ll s,f,t,v; scanf("%lld %lld %lld",&n,&m,&s); for(ll i = 1;i <= m;i ++) { scanf("%lld %lld %lld",&f,&t,&v); build(f,t,v); } for(ll i = 0;i <= n;i ++) { if(spfa(i) == -1) { puts("-1"); return 0; } } spfa(s); for(ll i = 1;i <= n;i ++) if(dis[i] >= INF) puts("NoPath"); else printf("%lld\n",dis[i]); return 0;}
严格次短路:
#include<iostream>#include<cstdio>#include<queue>#include<algorithm>#include<cstring>using namespace std;const int maxn = 2000000;struct Edge{ int from, to, cost;}es[maxn];int first[maxn], nxt[maxn] , tot = 0;long long zd[maxn], cd[maxn];bool used[maxn];queue < int > q;void build(int f, int t, int d){ es[++tot] = (Edge){f,t,d}; nxt[tot] = first[f]; first[f] = tot;}void spfa(int s){ zd[s] = 0; q.push(s); used[s] = 1; while(!q.empty()) { int u = q.front(); q.pop(); used[u] = 0; for(int i = first[u]; i != -1; i = nxt[i]) { int v = es[i].to; if(zd[v] > zd[u] + es[i].cost) { cd[v] = zd[v]; zd[v] = zd[u] + es[i].cost; if(!used[v]) { q.push(v); used[v] = 1; } } else if(cd[v] > zd[u] + es[i].cost && zd[v] < zd[u] + es[i].cost) { cd[v] = zd[u] + es[i].cost; if(!used[v]) { q.push(v); used[v] = 1; } } else if(cd[v] > cd[u] + es[i].cost ) { cd[v] = cd[u] + es[i].cost; if(!used[v]) { q.push(v); used[v] = 1; } } } }}
树的直径:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int SZ=100000+10;int first[SZ],nxt[SZ<<1];struct edge{ int from,to;}es[SZ<<1];int tot=0,n;void build(int ff,int tt){ es[++tot]=(edge){ff,tt}; nxt[tot]=first[ff]; first[ff]=tot;}int ans=0,pos;void dfs(int u,int f,int val){ if(val>ans) { ans=val; pos=u; } for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; if(v==f) continue; dfs(v,u,val+1); }}int main(){ memset(first,-1,sizeof(first)); int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int l,r; scanf("%d%d",&l,&r); if(l) build(l,i),build(i,l); if(r) build(r,i),build(i,r); } dfs(1,1,0); ans=0; dfs(pos,1,0); cout<<ans<<endl; return 0;}
0 0
- 【模板】其他图论
- play1跳转指定其他模板
- 公众号-所属行业模板消息-IT服务 -其他-其他
- Thinkphp 模板 html跳转其他网站
- Day48、模板特化、智能指针、模板的其他特性
- DedeCMS-----9、DedeCMS模板文件引入其他模板文件
- 1.3 神奇的其他图论算法
- 图论模板
- 图论模板
- 图论模板
- 图论模板
- 图论模板
- 图论模板整理
- ACM图论模板
- 图论总结模板
- 图论常用模板
- 图论常用模板
- 模板之图论
- python基础
- javaFile文件处理
- 双态运维下,老司机是怎么玩CMDB的?
- slf4j、logback和log4j的关系
- LevelDB源码分析5-Arena.md
- 【模板】其他图论
- ubuntu14.04出现的依赖问题
- OutputCache概念学习
- c++中的4种显式类型的转换
- c++笔记(9):联编、虚函数和多态性、异质表
- winform DataGridView 属性说明
- activity的一些属性值详解
- 传统企业互联网转型升级新玩法:技术合伙
- springMVC拦截器处理ajax请求及数据返回