消息传递--树形dp--50?!
1.调了半天才50%
思路:11.先统计每个点所连点子树大小,贪心先遍历树大的
12.每个点都模拟一遍,dfs用上个点的时间+1,同时for遍历时,父节点的t也要加
P2018 消息传递 - 洛谷
#include<bits/stdc++.h>
using namespace std;
#define N 100011
typedef long long ll;
int n;
struct no
{int v;int id;
};
vector<no> mp[1010];
map<int,vector<int>> a;
ll ma=0,mi=0x3f3f3f3f3f3f3f3fLL;
int d[1010];
int son[1010];
bool bo[1010];
bool cmp(no a,no b) {//if(mp[a.v].size()==mp[b.v].size())return a.id>b.id;//return mp[a.v].size()>mp[b.v].size();
}
int t=1;
int ss(int i)
{bo[i]=true;//cout<<i<<"///"<<endl;if(mp[i].size()==1) return son[i]=1;if(son[i]!=-1) return son[i];int s=1;for(auto v:mp[i]){if(!bo[v.v]){s+=ss(v.v);}}//cout<<i<<"//"<<s<<endl;return son[i]=s;
}
void dfs(int s) {for(auto v:mp[s]) {if(!d[v.v]) {d[v.v]=d[s]+1;dfs(v.v);d[s]++;}}ma=max(ma,(ll)d[s]);
}
int main() {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;for(int i=2; i<=n; i++) {int x;cin>>x;no a,b;a.v=x;b.v=i;mp[i].push_back(a);mp[x].push_back(b);}memset(son,-1,sizeof(son));ss(1);//for(int i=1;i<=n;i++) cout<<i<<"//"<<son[i]<<endl;if(mp[1].size()==n-1) {cout<<n<<endl;for(int i=1; i<=n; i++) cout<<i<<" ";}else {for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++){for(int k=0;k<mp[j].size();k++){if(son[mp[j][k].v]>son[j]){mp[j][k].id=son[mp[j][k].v]-son[j];}else mp[j][k].id=son[mp[j][k].v];}sort(mp[j].begin(),mp[j].end(),cmp);}memset(d,0,sizeof(d));d[i]=1;dfs(i);mi=min(mi,ma);a[ma].push_back(i);ma=0;}sort(a[mi].begin(),a[mi].end());cout<<mi<<endl;for(int v:a[mi]) cout<<v<<" ";}return 0;
}