zoukankan      html  css  js  c++  java
  • 战略威慑【LCA】【树的直径】

    题目:

    在这里插入图片描述


    思路:

    我们可以暴力枚举其中一条路径,那么问题就是在剩余的路径中找到一条长度最长的来匹配。
    所以其实就是暴力枚举+树的直径。
    枚举完一条路径后,求出端点的LCALCA,然后暴力标记已经使用过的的点。然后原本的一棵树就被分为了很多棵树。在每一个树中分别跑直径即可。
    时间复杂度O(n2logn+n3)O(n^2log n+n^3)


    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N=210,LG=10;
    int n,tot,ans,cnt,maxlen,head[N],f[N][LG+1],dep[N],g[N];
    bool flag[N]; 
    
    struct edge
    {
    	int next,to;
    }e[N*2];
    
    void add(int from,int to)
    {
    	e[++tot].to=to;
    	e[tot].next=head[from];
    	head[from]=tot;
    }
    
    void dfs(int x,int fa)
    {
    	dep[x]=dep[fa]+1; f[x][0]=fa;
    	for (int i=1;i<=LG;i++)
    		f[x][i]=f[f[x][i-1]][i-1];
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if (v!=fa) dfs(v,x);
    	}
    }
    
    int lca(int x,int y)
    {
    	if (dep[x]<dep[y]) swap(x,y);
    	for (int i=LG;i>=0;i--)
    		if (dep[f[x][i]]>=dep[y]) x=f[x][i];
    	if (x==y) return x;
    	for (int i=LG;i>=0;i--)
    		if (f[x][i]!=f[y][i])
    		{
    			x=f[x][i];
    			y=f[y][i];
    		}
    	return f[x][0];
    }
    
    void update(int x,int y)
    {
    	flag[x]=flag[y]=1;
    	for (;x!=y;x=f[x][0])
    		flag[x]=1,cnt++;
    }
    
    void dp(int x,int fa)
    {
    	flag[x]=1; g[x]=0;
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if (v!=fa && !flag[v])
    		{
    			dp(v,x);
    			maxlen=max(maxlen,g[x]+g[v]+1);
    			g[x]=max(g[x],g[v]+1);
    		}
    	}
    }
    
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d",&n);
    	for (int i=1,x,y;i<n;i++)
    	{
    		scanf("%d%d",&x,&y);
    		add(x,y); add(y,x);
    	}
    	dfs(1,0);
    	for (int i=1;i<=n;i++)
    		for (int j=i+1;j<=n;j++)
    		{
    			memset(flag,0,sizeof(flag));
    			int LCA=lca(i,j);
    			cnt=maxlen=0;
    			update(i,LCA); update(j,LCA);
    			for (int i=1;i<=n;i++)
    				if (!flag[i]) dp(i,0);
    			ans=max(ans,cnt*maxlen);
    		}
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    奇数阶魔方问题
    《DSP using MATLAB》示例9.3
    《DSP using MATLAB》示例9.2
    《DSP using MATLAB》示例9.1
    找个目标很重要
    《DSP using MATLAB》示例Example 8.30
    《DSP using MATLAB》示例Example 8.29
    《DSP using MATLAB》示例Example 8.28
    《DSP using MATLAB》示例Example 8.27
    《DSP using MATLAB》示例Example 8.26
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11997983.html
Copyright © 2011-2022 走看看