Problem A: Tree
Time Limit: 2 Sec Memory Limit: 1280 MBSubmit: 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;
}