题目描述
马奥雷利亚诺布恩迪亚上校发动了他的第三十二次战争,让我们祝他好运。马孔多附近有n个城市,有n-1条双向道路连通这些城市。上校想通过摧毁两条公路的方式对当局予以威慑。但是上校的老师告诉他为了战略目的这两条路不可以有共同的城市。这次行动对当局的威慑效果将等于两条路径的长度的乘积。假设每条道路的长度等于1,并且路径的长度等于道路的数量。请你帮上校造成最大的威慑。
输入
单组测试数据。第一行是一个整数 n (2≤n≤200) ,n是这个马孔多附近城市的数量。接下来n-1行是道路的信息,每一行是两个整数ai,bi,它们是城市的编号,表示ai和bi之间有一条道路直接连通。(1≤ai,bi≤n)。
输出
输出最大的威慑。
样例输入
4
1 2
2 3
3 4
样例输出
1
提示
对于35%的数据, n <= 10
对于75%的数据, n <= 100
对于100%的数据, n <= 200
思路
枚举每一条边,对每一条边,拆除这条边求树的直径,计算答案的最大值
代码实现
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N= 1005;
const int INF=0x3f3f3f3f;
const int mod=1000000007;
const double eps=1e-12;
typedef pair<double,double>P;
struct node
{
int to,nxt;
}E[N];
int cnt,head[N],dp[N],ans;
bool vis[N];
int tot1,tmp;
void add(int u,int v)
{
E[++cnt].nxt=v;
E[cnt].to=head[u];
head[u]=cnt;
}
int n;
void dfs(int u)
{
vis[u]=true;
for(int i=head[u];i;i=E[i].to)
{
int v=E[i].nxt;
if(vis[v]) continue;
dfs(v);
tmp=max(tmp,dp[u]+dp[v]+1);
dp[u]=max(dp[v]+1,dp[u]);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
for(int i=1;i<=cnt;i+=2)
{
memset(dp,0,sizeof(dp));
memset(vis,false,sizeof(vis));
vis[E[i].nxt]=vis[E[i+1].nxt]=true;
tmp=0;
dfs(E[i].nxt);
tot1=tmp;
tmp=0;
dfs(E[i+1].nxt);
ans=max(ans,tmp*tot1);
}
printf("%d\n",ans);
return 0;
}