战略威慑(树的直径)

题目描述
马奥雷利亚诺布恩迪亚上校发动了他的第三十二次战争,让我们祝他好运。马孔多附近有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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值