http://codeforces.com/problemset/problem/1292/C
题意:
给出一棵树,n个点,你将0至n-2这n-1个数填到每条边上。一条路径的权值为最小的没有出现过的自然数,求所有路径的权值和的最大值。
解析:
没有出现过的自然数,可以这么理解,如果这条路径上包含了0、1,那么权值为2。
也就是说,答案变为:包含0的路径数+包含01的路径数+包含012的路径数+……
那么考虑dp[x][y]表示将数填到x到y这条路的最大值
d
p
[
X
]
[
Y
]
=
m
a
x
(
d
p
[
X
]
[
K
]
,
d
p
[
Q
]
[
Y
]
)
+
s
i
z
X
⋅
s
i
z
Y
dp[X][Y]=max(dp[X][K],dp[Q][Y])+siz_X\cdot siz_Y
dp[X][Y]=max(dp[X][K],dp[Q][Y])+sizX⋅sizY
先把长度为1的链放队列再做bfs,不断延长即可。
代码:
/*
* Author : Jk_Chen
* Date : 2020-01-25-14.52.27
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<<x<<'\n'
const LL mod=1e9+7;
const int maxn=3e3+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
int n;
#define rep_e(i,p,u) for(int i=head[p],u=to[i];i;i=nex[i],u=to[i])
int head[maxn],to[maxn<<1],nex[maxn<<1],now;
void add(int a,int b){
nex[++now]=head[a];head[a]=now;to[now]=b;
}
void init_edge(){
memset(head,0,sizeof head);
now=0;
}
/*_________________________________________________________edge*/
int siz[maxn],fa[maxn];
struct node{
int x,y,top,son;
node(int x,int y,int top,int son):x(x),y(y),top(top),son(son){}
node(){}
};
vector<node>V;
void dfs0(int p,int _fa){
siz[p]=1;
rep_e(i,p,u){
if(u==_fa)continue;
V.push_back(node(p,u,p,u));
fa[u]=p;
dfs0(u,p);
siz[p]+=siz[u];
}
}
queue<node>Q;
LL dp[maxn][maxn];
void bfs(){
for(auto P:V){
dp[P.x][P.y]=dp[P.y][P.x]=(siz[1]-siz[P.son])*siz[P.son];
Q.push(P);
}
// x up,y down
while(!Q.empty()){
node P=Q.front();Q.pop();
if(P.top!=-1){
// 往上
if(P.x!=1){
LL add=(siz[1]-siz[P.x])*siz[P.y];
if(dp[fa[P.x]][P.y]==0)Q.push(node(fa[P.x],P.y,fa[P.x],P.x));
dp[fa[P.x]][P.y]=dp[P.y][fa[P.x]]=max(dp[P.y][fa[P.x]],dp[P.x][P.y]+add);
}
rep_e(i,P.x,u){
if(u==P.son||u==fa[P.x])continue;
LL add=siz[u]*siz[P.y];
if(dp[u][P.y]==0)Q.push(node(u,P.y,-1,-1));
dp[u][P.y]=dp[P.y][u]=max(dp[P.y][u],dp[P.x][P.y]+add);
}
rep_e(i,P.y,u){
if(u==fa[P.y])continue;
LL add=(siz[1]-siz[P.son])*siz[u];
if(dp[P.x][u]==0)Q.push(node(P.x,u,P.x,P.son));
dp[P.x][u]=dp[u][P.x]=max(dp[u][P.x],dp[P.x][P.y]+add);
}
}
else{
rep_e(i,P.y,u){
if(u==fa[P.y])continue;
LL add=siz[P.x]*siz[u];
if(dp[P.x][u]==0)Q.push(node(P.x,u,-1,-1));
dp[P.x][u]=dp[u][P.x]=max(dp[u][P.x],dp[P.x][P.y]+add);
}
rep_e(i,P.x,u){
if(u==fa[P.x])continue;
LL add=siz[P.y]*siz[u];
if(dp[P.y][u]==0)Q.push(node(P.y,u,-1,-1));
dp[P.y][u]=dp[u][P.y]=max(dp[u][P.y],dp[P.x][P.y]+add);
}
}
}
}
int main(){
n=rd;
rep(i,1,n-1){
int a=rd,b=rd;
add(a,b);add(b,a);
}
dfs0(1,-1);
bfs();
LL mx=0;
rep(i,1,n)rep(j,1,n)mx=max(mx,dp[i][j]);
printf("%lld\n",mx);
return 0;
}
/*_________________________________________________________end*/