[51nod][cf468D]1558 树中的配对
Posted Swm_sxt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[51nod][cf468D]1558 树中的配对相关的知识,希望对你有一定的参考价值。
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1558
不是很懂dalao们用线段树是怎么写的……
反正找出重心以后每个子树一个堆,再来个全局堆就吼了
#include<queue> #include<stdio.h> #include<algorithm> #define MN 100001 using namespace std; int read_p,read_ca; inline int read(){ read_p=0;read_ca=getchar(); while(read_ca<‘0‘||read_ca>‘9‘) read_ca=getchar(); while(read_ca>=‘0‘&&read_ca<=‘9‘) read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p; } struct na{int y,z,ne;}b[MN<<1]; struct ma{int x,y;ma(int _x=0,int _y=0):x(_x),y(_y){}}; bool operator < (ma a,ma b){return a.x<b.x;} priority_queue<ma> q[MN],Q,_q; int n,m,l[MN],x,y,z,ro,mi=1e9,si[MN],nm=0,num=0,be[MN]; long long MMH; inline void in(int x,int y,int z){b[++num].y=y;b[num].z=z;b[num].ne=l[x];l[x]=num;} inline int min(int a,int b){return a<b?a:b;} int dfs(int x,int f){ int S=1,s,u=0; for (register int i=l[x];i;i=b[i].ne) if (b[i].y!=f){ s=dfs(b[i].y,x); if (u<s) u=s; S+=s; MMH+=1LL*b[i].z*min(s,n-s); } if (n-S>u) u=n-S; if (u<mi) ro=x,mi=u; return S; } void DFS(int x,int f,int d){ q[d].push(ma{-x,d});si[d]++;be[x]=d; for (register int i=l[x];i;i=b[i].ne) if (b[i].y!=f) DFS(b[i].y,x,d); } int work(int u){ while (_q.top().x!=q[_q.top().y].top().x||q[_q.top().y].empty()) _q.pop(); ma o; if (_q.top().y==u) o=_q.top(),_q.pop(); while (_q.top().x!=q[_q.top().y].top().x||q[_q.top().y].empty()) _q.pop(); u=_q.top().y; if (o.x) _q.push(o); return u; } int main(){ register int i; n=read(); if (n==1) return puts("0\n1"),0; for (i=1;i<n;i++) x=read(),y=read(),z=read(),in(x,y,z),in(y,x,z); dfs(1,0); q[0].push(ma{-ro,0});_q.push(ma{-ro,0});si[0]=1; for (i=l[ro];i;i=b[i].ne) DFS(b[i].y,ro,++nm),Q.push(ma{si[nm]<<1,nm}),_q.push(ma(q[nm].top().x,nm)); printf("%lld\n",MMH<<1); for (i=1;i<=n;i++){ while (Q.top().x!=si[Q.top().y]+q[Q.top().y].size()) Q.pop(); if (be[i]==Q.top().y||Q.top().x<n-i+1) m=work(be[i]);else m=Q.top().y; if (i==ro&&-q[m].top().x>ro&&!q[0].empty()&&Q.top().x<n-i+1) m=0; printf("%d ",-q[m].top().x); q[m].pop();si[be[i]]--;if (!q[m].empty())_q.push(ma(q[m].top().x,m)); Q.push(ma(si[m]+q[m].size(),m));Q.push(ma(si[be[i]]+q[be[i]].size(),be[i])); } }
以上是关于[51nod][cf468D]1558 树中的配对的主要内容,如果未能解决你的问题,请参考以下文章