zoukankan      html  css  js  c++  java
  • CF1292C Xenon's Attack on the Gangs

    题目

    Input

    The first line contains an integer n (2≤n≤3000), the number of gangs in the network.

    Each of the next n−1 lines contains integers ui and vi (1≤ui,vi≤n; ui≠vi), indicating there's a direct link between gangs ui and vi.

    It's guaranteed that links are placed in such a way that each pair of gangs will be connected by exactly one simple path.

    output

    Print the maximum possible value of S — the number of password layers in the gangs' network.

    Examples

    Input

    3
    1 2
    2 3

    Output

    3

    Input

    5
    1 2
    1 3
    1 4
    3 5

    Output

    10

    Note

    题意

    给n个结点,n-1条无向边。即一棵树。我们需要给这n-1条边赋上0~ n-2不重复的值。mex(u,v)表示从结点u到结点v经过的边权值中没有出现的最小非负整数。计算下面等式的最大值

     

    分析

    假设求1-2-3-4这样的链的结果,那么假如我们已经知道了它的子结果,1-2-3和2-3-4的结果,我们要从这个结果推出1-2-3-4结果,那么根据我们的分析,从1-2-3和2-3-4变成1-2-3-4都是加上1-2-3-4这条链两头点的乘积(就是这棵树中有多少条链能够覆盖这条链,他们都能得到这个加成),既然加的数值一样,那么肯定选他们两个中大的那个啦。数量的话很简单,对于x-…-y这条链来说,x那边的点的个数就是以y为根,x为子树顶点的子树的点数量,另一边就正好相反,就是刚才说的num[root][u] num[root][u]num[root][u]可以得到,而1-2-3和2-3-4的获得,就可以用fa[root][u] fa[root][u]fa[root][u],同样对于x-…-y这条链来说,fa[x][y] fa[x][y]fa[x][y]就是x-…-y这条链中,与y直接相连的那个点。

    代码

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<stack>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define per(i,a,b) for(int i=a;i>=b;i--)
    #define inf 0x3f3f3f3f
    const int MAXN = 3e3+5;
    vector<int>v[MAXN];
    ll fa[MAXN][MAXN],num[MAXN][MAXN],dp[MAXN][MAXN],root;
    void dfs(int u,int f){
        num[root][u]=1;
        int len=v[u].size();
        rep(i,0,len-1){
            int y=v[u][i];
            if(y==f)continue;
            fa[root][y]=u;
            dfs(y,u);
            num[root][u]+=num[root][y];
        }
    }
    ll solve(int x,int y){
        if(x==y)return 0;
        if(dp[x][y])return dp[x][y];
        return dp[x][y]=num[x][y]*num[y][x]+max(solve(x,fa[x][y]),solve(y,fa[y][x]));
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,x,y;
        while(cin>>n){
            rep(i,1,n)v[i].clear();
            memset(fa,0,sizeof(fa));
            memset(num,0,sizeof(num));
            memset(dp,0,sizeof(dp));
            rep(i,1,n-1){
                cin>>x>>y;
                v[x].push_back(y);
                v[y].push_back(x);
            }
            rep(i,1,n){
                root=i;
                dfs(i,-1);
            }
            ll ans=0;
            rep(i,1,n){
                rep(j,i+1,n){
                    ans=max(ans,solve(i,j));
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }

  • 相关阅读:
    RSA加密算法
    ios 经典错误
    C--指针函数,static
    svn---命令行操作
    iOS中的自由桥接
    ios--socket
    ios错误修改了系统头文件
    ios数据库FMDB
    CoreDate的使用
    ios简单数据库运用
  • 原文地址:https://www.cnblogs.com/Vocanda/p/12679570.html
Copyright © 2011-2022 走看看