CF1292C Xenon's Attack on the Gangs

topic

 

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

 

Title

For n nodes, n-1 undirected edges. That is a tree. We need to assign 0 ~ n-2 unique values ​​to these n-1 edges. mex (u, v) represents the smallest non-negative integer that does not appear in the edge weights passing from node u to node v. Calculate the maximum value of the following equation

 

analysis

 According to the above formula, a conclusion can be drawn, that is, as long as the contribution of each side is considered, each side must have a contribution.

Suppose to find the result of a chain like 1-2-3-4, then if we already know its sub-results, the results of 1-2-3 and 2-3-4, we need to derive 1-2- from this result 3-4 results, then according to our analysis, from 1-2-3 and 2-3-4 to 1-2-3-4 are added to the product of the two ends of the chain 1-2-3-4 (That is, how many chains in this tree can cover this chain, they can all get this bonus), since the added value is the same, then definitely choose the larger of the two of them. The number is very simple. For the chain of x -...- y, the number of points on the side of x is the number of points in the subtree with y as the root and x as the vertex of the subtree. Just said num [root] [u] num [root] [u] num [root] [u] can be obtained, and 1-2-3 and 2-3-4 can be obtained using fa [root] [ u] fa [root] [u] fa [root] [u], also for the x -...- y chain, fa [x] [y] fa [x] [y] fa [x] [y ] Is the point directly connected to y in the chain x -...- y.

Code

#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;
}

 

 

 

Guess you like

Origin www.cnblogs.com/Vocanda/p/12679570.html