队内训练赛--A(Tree)

Problem A: Tree

Time Limit: 2 Sec  Memory Limit: 1280 MB
Submit: 29  Solved: 6
[ Submit][ Status][ Web Board]

Description

众所周知,华农是武汉面积最大的校园之一,我们想象华农为n的点组成的一棵树,我们知道每棵树一共有n * (n - 1) / 2条不同的链,而每一条链由若干条边组成,我们定义树上的每条边的价值为这条链在所有链上出现的次数,也就是如果这条边在一条链上出现过,次数就加一,没有出现过就加零,现在需要聪明的你求出这棵树的价值最大的那条边,输出这条边的价值。

Input

第一行T,表示测试组数(T <= 50)

接着T组数据。

每组数据包括顶点数n(n >= 2, n <= 200000)

(90%的数据n<=100,100%数据<=200000)

接下来n - 1行,每一行两个数u, v表示树上有一条u 到 v的边

Output

一个整数,表示最大价值的那条边的价值

Sample Input

231 21 351 21 42 32 5

Sample Output

Case #1: 2Case #2: 6

题目大意:中文题面

思路:
用dfs遍历这棵树,记录每个点作为根的次数,找到第i条边的终点(作为根的次数较少的点)记为min,在用(n-min)*min即为所求

代码:
#include <bits/stdc++.h>
const int maxn = 2e5 + 100;
using namespace std;
typedef struct{
    int u,v;
}EDGE;
EDGE edge[maxn];
vector<int> g[maxn];
bool vis[maxn];
int r;
int n;
int dp[maxn];
void chuangjian()
{
    memset(vis, false, sizeof(vis));
    for(int i = 0; i <= n; i++)
        g[i].clear();
    r = 1;
}
void dfs(int x)
{
    vis[x]=true;
    dp[x]=1;
    for(int i=0;i<g[x].size();i++)
    {
        int y=g[x][i];
        if(vis[y]!=true)
        {
            dfs[y];
            dp[x]+=dp[y];
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int u,v;
        chuangjian();
        for(int i=0;i<n-1;i++)
        {
            scanf("%d %d",&u,&v);
            edge[i].u=u;
            edge[i].v=v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(r);
        int MAX=0;
        for(int i=0;i<n-1;i++)
        {
            int u=edge[i].u;
            int v=edge[i].v;
            LL M=min(dp[u],dp[v]);
            if(MAX<M*(n-M))
            {
                MAX=M;
            }
        }
        cout<<MAX<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值