• 模板最近的共同祖先


    LCA tarjan 离线算法

    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int maxn = 40010;
    int first[maxn], head[maxn], cnt, sum;
    struct edge
    {
    	int u, v, w, next;
    }e[maxn*2], qe[maxn], Q[maxn];
    int ans[maxn];
    int f[maxn], vis[maxn];
    int d[maxn];
    void AddEdge(int u, int v, int w)
    {
    	e[cnt].u = u;
    	e[cnt].v = v;
    	e[cnt].w = w;
    	e[cnt].next = first[u];
    	first[u] = cnt++;
    	e[cnt].u = v;
    	e[cnt].v = u;
    	e[cnt].w = w;
    	e[cnt].next = first[v];
    	first[v] = cnt++;
    }
    
    int find(int x)
    {
    	if(f[x] != x)
    		return f[x] = find(f[x]);
    	return f[x];
    }
    void LCA(int u, int k)
    {
    	f[u] = u;
    	d[u] = k;
    	vis[u] = true;
    	for(int i = first[u]; i != -1; i = e[i].next)
    	{
    		int v = e[i].v;
    		if(vis[v])
    			continue;	
    		LCA(v, k + e[i].w);
    		f[v] = u;
    	}
    	for(int i = head[u]; i != -1; i = qe[i].next)
    	{
    		int v = qe[i].v;
    		if(vis[v])
    		{
    			ans[qe[i].w] = find(v);
    		}
    	}
    } 

    LCA 转RMQ的在线算法

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 200010;
    struct edge
    {
    	int u, v, w, next;
    }edges[maxn*2], e[maxn];
    
    int E[maxn*2], H[maxn*2], I[maxn*2], L[maxn], R[maxn];
    int dp[maxn*2][40];
    int cnt, clock, dfn;
    int first[maxn];
    int a[maxn<<2];
    int b[maxn];
    int add[maxn<<2];
    int degree[maxn];
    int vis[maxn];
    void AddEdge(int u, int v, int w)
    {
    	edges[cnt].u = u;
    	edges[cnt].v = v;
    	edges[cnt].w = w;
    	edges[cnt].next = first[u];
    	first[u] = cnt++;
    	edges[cnt].u = v;
    	edges[cnt].v = u;
    	edges[cnt].w = w;
    	edges[cnt].next = first[v];
    	first[v] = cnt++;	
    }
    void dfs(int u, int fa, int dep)
    {
    	E[++clock] = u;
    	H[clock] = dep;
    	I[u] = clock;
    	L[u] = ++dfn;
    	b[dfn] = u;
    	for(int i = first[u]; i != -1; i = edges[i].next)
    	{
    		int v = edges[i].v;
    		if(v == fa)
    			continue;
    		if(vis[v])
    			continue;
    		vis[v] = true;
    		dfs(v, u, dep+1);
    		E[++clock] = u;
    		H[clock] = dep;
    	}
    	R[u] = dfn;
    }
    
    void RMQ_init(int n)
    {
    	for(int i = 1; i <= n; i++)
    		dp[i][0] = i;
    	for(int j = 1; (1<<j) <= n; j++)
    		for(int i = 1; i+(1<<j)-1 <= n; i++)
    		{
    			if(H[dp[i][j-1]] < H[dp[i+(1<<(j-1))][j-1]])
    				dp[i][j] = dp[i][j-1];
    			else
    				dp[i][j] = dp[i+(1<<(j-1))][j-1];
    		}
    }
    int RMQ(int l, int r)
    {
    	l = I[l], r = I[r];
    	if(l > r)
    		swap(l, r);
    	int len = r-l+1, k = 0;
    	while((1<<k) <= len)
    		k++;
    	k--;
    	if(H[dp[l][k]] < H[dp[r-(1<<k)+1][k]])
    		return E[dp[l][k]];
    	else
    		return E[dp[r-(1<<k)+1][k]];
    }


    LCA倍增法

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 20010;
    const int INF = 999999999;
    int anc[maxn][16], maxcost[maxn][16];
    int fa[maxn], L[maxn], cost[maxn], vis[maxn];
    int n, m;
    int first[maxn], cnt;
    struct edge
    {
    	int u, v, next;
    }e[maxn*2];
    
    void AddEdge(int u, int v)
    {
    	e[cnt].v = v;
    	e[cnt].next = first[u];
    	first[u] = cnt++;
    	e[cnt].v = u;
    	e[cnt].next = first[v];
    	first[v] = cnt++;
    }
    
    void pre()
    {
    	for(int i = 1; i <= n; i++)
    	{
    		anc[i][0] = fa[i]; maxcost[i][0] = cost[i];
    		for(int j = 1; (1<<j) < n; j++)
    			anc[i][j] = -1;
    	}
    	for(int j = 1; (1<<j) < n; j++)
    		for(int i = 1; i <= n; i++)
    			if(anc[i][j-1] != -1)
    			{
    				int a = anc[i][j-1];
    				anc[i][j] = anc[a][j-1];
    				maxcost[i][j] = max(maxcost[i][j-1], maxcost[a][j-1]);
    			}
    	
    }
    
    int query(int p, int q)
    {
    	int tmp, log, i;
    	if(L[p] < L[q])
    		swap(p, q);
    	for(log = 1; (1<<log) <= L[p]; log++);
    	log--;
    	
    	int ans = -INF;
    	for(int i = log; i >= 0; i--)
    		if(L[p] - (1<<i) >= L[q])
    		{
    			ans = max(ans, maxcost[p][i]);
    			p = anc[p][i];
    		}
    	if(p == q)
    		return ans;
    	for(int i = log; i >= 0; i--)
    	{
    		if(anc[p][i] != -1 && anc[p][i] != anc[q][i])
    		{
    			ans = max(ans, maxcost[p][i]);
    			ans = max(ans, maxcost[q][i]);
    			p = anc[p][i];
    			q = anc[q][i];
    		}
    	}
    	ans = max(ans, cost[p]);
    	ans = max(ans, cost[q]);
    	return ans;
    }
    void dfs(int u)
    {
    	for(int i = first[u]; i != -1; i = e2[i].next)
    	{
    		int v = e[i].v;
    		if(vis[v])
    			continue;
    		vis[v] = 1;
    		fa[v] = u;
    		L[v] = L[u]+1;
    		dfs(v);
    	}
    }


     

    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    用于创建和管理 Azure 虚拟机的常用 PowerShell 命令
    在 Azure Resource Manager 中为虚拟机设置密钥保管库
    使用 Azure 资源管理器向 Windows VM 应用策略
    Azure 门户中基于角色的访问控制入门
    为 Azure Resource Manager 中的虚拟机设置 WinRM 访问权限
    如何加密 Windows VM 上的虚拟磁盘
    适用于 Windows VM 的 Azure 示例基础结构演练
    Azure 中虚拟机的备份和还原选项
    1.1 基本算法和记号
    tomcat的class加载的优先顺序
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4843985.html
Copyright © 2020-2023  润新知