#暴力/樹的直徑# [nssl 1438] 戰略威懾

題目

在這裏插入圖片描述


解題思路

O(n3)O(n^3)可過。

我們暴力枚舉每兩個點,然後對剩下的點求樹的直徑(最長鏈),相乘既是答案。


代碼

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; 
const int N=800; 
struct node{int y,next;}a[N*2];
int n,tot,head[N],ans,f[N],d[N],num,g; bool v[N]; 
void add(int x,int y){
	a[++tot]=(node){y,head[x]}; head[x]=tot; 
	a[++tot]=(node){x,head[y]}; head[y]=tot; 
}
void dp(int x){
	if (v[x]) return; 
	v[x]=1; 
	for(int i=head[x];i;i=a[i].next){
		int y=a[i].y; 
		if (v[y]) continue; dp(y); 
		ans=max(ans,d[x]+d[y]+1); 
		d[x]=max(d[x],d[y]+1); 
	}
}
void dfs(int x,int fa,int jq){
	if (x==jq) {v[x]=1; num++; return;}
	for(int i=head[x];i;i=a[i].next){
		int y=a[i].y; 
		if (y==fa) continue; 
		dfs(y,x,jq); 
		if (v[y]) v[x]=1,num++; 
	}
}
int main(){
	scanf("%d",&n); 
	for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y); 
    for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){
    	memset(d,0,sizeof(d)); 
    	memset(v,0,sizeof(v)); ans=num=0; 
    	dfs(i,0,j); 
    	for(int j=1;j<=n;j++) if (!v[j]) {dp(j); break;}
    	g=max(g,ans*(num-1));  
	}
	printf("%d",g); 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章