https://vjudge.net/problem/计蒜客-44317/origin
让最大值走得最多就好了,让最大值走最长链的长度,然后把最长链上的点都打上标记,再从所有没有被标记的点里找次长链,让次大值跑
这个题我最后一小时写慌了,思路乱了,队友写得很妙,tql
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) using namespace std; long long n,k,ans,cnt,f,x,s; long long a[N],d[N],son[N]; bool vis[N]; struct tree{ long long id; long long dep; bool operator < (const tree &x) const{ return dep>x.dep; } }b[N]; struct node{ long long n; node *next; }*e[N]; void in(long long &x){ long long y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(long long x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } void push(long long x,long long y){ node *p; p=new node(); p->n=y; if(e[x]==0) e[x]=p; else{ p->next=e[x]->next; e[x]->next=p; } } void dfs(long long x){ b[x].dep=1; for(node *i=e[x];i;i=i->next){ if(i->n!=d[x]){ dfs(i->n); if(b[i->n].dep+1>b[x].dep){ b[x].dep=b[i->n].dep+1; son[x]=i->n; } } } } bool cmp(long long x,long long y){ return x>y; } signed main(){ in(n);in(k);d[1]=1; For(i,1,k) in(a[i]); For(i,2,n){ in(x); d[i]=++x; push(i,x);push(x,i); } For(i,1,n) b[i].id=i; dfs(1); sort(a+1,a+n+1,cmp); sort(b+1,b+n+1); b[1].dep--; For(i,1,n){ if(!vis[b[i].id]){ vis[b[i].id]=1; ans+=a[++cnt]*b[i].dep; s=son[b[i].id]; while(s){ vis[s]=1; s=son[s]; } } } o(ans); return 0; }