SSLOJ 1438.戰略威懾【樹的直徑】【樹形dp】


題目:

傳送門


題意:

任選兩條路徑,在兩條路徑沒有任何交點的情況下,問兩條路徑長度的乘積最大是多少


分析:

我們用dfsdfs來枚舉要刪去哪一條邊,這樣就可以保證路徑沒有任何一個交點
之後用樹形dpdp來求以這條邊兩個端點爲根的子樹的直徑是多少


代碼:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
struct node{
	int to,next;
}e[405];
int ls[405],cnt=0;
void add(int x,int y)
{
	e[cnt]=(node){y,ls[x]};
	ls[x]=cnt++;
	return;
}
int dep[205],king;
void dfs(int k,int fa,int root)
{
	for(int i=ls[k];~i;i=e[i].next)
	{
		int v=e[i].to;
		if(v==fa||v==root) continue;
		dfs(v,k,root);
		king=max(king,dep[k]+dep[v]+1);
		dep[k]=max(dep[k],dep[v]+1);
	}
}
int ans=0;
void cut(int k,int fa)
{
	for(int i=ls[k];~i;i=e[i].next) 
	{
		int v=e[i].to;
		if(v==fa) continue;      
		memset(dep,0,sizeof(dep));
		king=0;dfs(k,0,v);int bc=king;
		king=0;dfs(v,0,k);
		ans=max(ans,bc*king);
		cut(v,k);
	}
	return;
}
int main()
{
	memset(ls,-1,sizeof(ls)); 
	int n=read();
	for(int i=1;i<n;i++) 
	{
		int x=read(),y=read();
		add(x,y);add(y,x);
	}
	cut(1,0);
	cout<<ans;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章