思路:
不难看出计算maxdist,就是一个子树中一个点到其它点的最大距离和次大距离之和。
那么就可以在每个点上求出到其它点的距离,这里求距离用到dp,
然后贪心地,只需要考虑每个点的最大距离和次大距离,就可以求出每个点的答案。
当然也以直接暴力
DP
D
P
,定义
dp[x][d]
d
p
[
x
]
[
d
]
为subtree(x)中最大到根距离为x的块数。
然后直接暴力转移即可。
code:
#include<bits/stdc++.h>
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i<i##_end_;i++)
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define db double
#define LL long long
#define INF 0x3f3f3f3f
#define Sz(a) sizeof(a)
#define mcl(a,b) memset(a,b,Sz(a))
#define mcp(a,b) memcpy(a,b,Sz(b))
#define pb push_back
template<class T>inline bool chkmin(T &x,T y){return y<x?x=y,1:0;}
template<class T>inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
inline LL Max(LL &x,LL y){return x>y?x:y;}
inline LL Min(LL &x,LL y){return x<y?x:y;}
#define N 52
#define M 502
int n;
struct edge{
int to,cost;
};
vector<edge>E[N];
int dp[M];
class Ethernet {
public:
int Mx;
int dfs(int x){
vector<int>dis;
dis.pb(0);
int res=0;
int &t=dp[x];
SREP(i,0,E[x].size()){
int y=E[x][i].to;
res+=dfs(y);
dis.pb(dp[y]+E[x][i].cost);
}
sort(dis.begin(),dis.end());//排序距离
while(dis.size()>1 && dis[dis.size()-1]+dis[dis.size()-2]>Mx){// judge and merge
res++;
dis.pop_back();
}
t=dis[dis.size()-1];
return res;
}
int connect(vector <int> parent, vector <int> dist, int maxDist) {
n=parent.size();
Mx=maxDist;
SREP(i,0,n)E[parent[i]].pb((edge){i+1,dist[i]});
return dfs(0)+1;
}
};
code(纯DP):
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <cassert>
#include <iostream>
#include <sstream>
using namespace std;
#define rep(i,a,n) for(int i=a,_n=n;i<_n;++i)
#define repp(i,a,n) for(int i=a,_n=n;i<=_n;++i)
#define per(i,a,n) for(int i=n-1,_a=a;i>=_a;--i)
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(x) ((int)(x).size())
#define accu accumulate
#define two(x) (1<<(x))
#define twol(x) (1ll<<(x))
#define clr(a) memset(a,0,sizeof(a))
#define debug(x) cout<<#x<<" = "<<x<<endl;
typedef vector<int> vi;
typedef vector<string> vs;
typedef long long ll;
typedef double db;
typedef long double ldb;
typedef pair<int,int>pii;
typedef vector<pii> vpii;
const int INF=0x3f3f3f3f;
int n;
struct node{
int v,w;
};
vector<node>E[55];
int dp[55][555],tmp[555];
void Min(int &x,int y){
if(y<x) x=y;
}
class Ethernet {
public:
void DP(int x,int f,int maxDist){
int ok=0;
for(int i=0;i<E[x].size();i++){
int V=E[x][i].v,W=E[x][i].w;
if(V==f) continue;
DP(V,x,maxDist);
for(int j=0;j<=maxDist;j++) tmp[j]=INF;
if(!ok){
for(int j=0;j<=maxDist;j++) Min(tmp[0],dp[V][j]+1);
for(int j=0;j+W<=maxDist;j++) Min(tmp[j+W],dp[V][j]);
}
else{
for(int t=0;t<=maxDist;t++) for(int j=0;j<=maxDist;j++) Min(tmp[t],dp[x][t]+dp[V][j]+1);
for(int j=0;j+W<=maxDist;j++){
for(int t=0;t<=maxDist;t++){
if(j+W+t<=maxDist) Min(tmp[max(t,j+W)],dp[x][t]+dp[V][j]);
}
}
}
for(int j=0;j<=maxDist;j++) dp[x][j]=tmp[j];
ok=1;
}
if(!ok){
dp[x][0]=0;
}
}
int connect(vector <int> parent, vector <int> dist, int maxDist) {
n=parent.size()+1;
memset(dp,63,sizeof(dp));
for(int i=0;i<=n;i++) E[i].clear();
for(int i=0;i<n-1;i++){
E[parent[i]].pb((node){i+1,dist[i]});
E[i+1].pb((node){parent[i],dist[i]});
}
DP(0,-1,maxDist);
int ans=INF;
for(int i=0;i<=maxDist;i++) Min(ans,dp[0][i]);
return ans+1;
}
};