【2016北京集训测试赛(八)】 直径 (虚树+树的直径)
2017-08-14 19:17
381 查看
Description
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=300010,Bas=20; int n,m,tot,bas,ho ,side [3],pre [Bas+1],dep ; ll far[2]; int timecnt,dfn ,rt ,cnt,newid ,H[N*10]; vector<int> use ; map<int,int> tree ; struct Edge{int v,w,next;}g[N*2+N*20]; struct WaitEdge{ int a,b,c,d; WaitEdge(){} WaitEdge(int aa,int bb,int cc,int dd){a=aa;b=bb;c=cc;d=dd;} void get(int &aa,int &bb,int &cc,int &dd){aa=a;bb=b;cc=c;dd=d;} }waitedge ; struct MT{ int a,as,b,bs; MT(){a=as=b=bs=-1;} void push(int c,int cs){ if(c>a) b=a, bs=as, a=c, as=cs; else if(c>b) b=c, bs=cs; } }mt ; inline void addEdge(int u,int v,int w,int *h){ if(u==v) return; g[++tot].v=v; g[tot].w=w; g[tot].next=h[u]; h[u]=tot; } void preDfs(int u,int fa,int deep){ dfn[u]=++timecnt; dep[u]=deep; pre[u][0]=fa; for(int i=1;i<=bas;i++) pre[u][i]=pre[pre[u][i-1]][i-1]; for(int i=ho[u],v;i;i=g[i].next){ if((v=g[i].v)!=fa){ preDfs(v,u,deep+1); mt[u].push(mt[v].a+1,mt[v].as); if(side[v][0]&&side[v][0]>side[u][0]) side[u][0]=side[v][0],side[u][1]=side[v][1],side[u][2]=side[v][2]; } } mt[u].push(0,u); if(mt[u].as!=-1&&mt[u].bs==-1){ side[u][0]=1; side[u][1]=side[u][2]=u; } else if(mt[u].as&&mt[u].bs&&mt[u].a+mt[u].b+1>side[u][0]){ side[u][0]=mt[u].a+mt[u].b+1; side[u][1]=mt[u].as; side[u][2]=mt[u].bs; } } int getLca(int a,int b){ if(dep[a]<dep[b]) swap(a,b); for(int i=bas;i>=0;i--) if(dep[pre[a][i]]>=dep[b]) a=pre[a][i]; if(a==b) return a; for(int i=bas;i>=0;i--) if(pre[a][i]!=pre[b][i]) a=pre[a][i], b=pre[b][i]; return pre[a][0]; } bool cmp(int x,int y){return dfn[x]<dfn[y];} int lis[N*10],K,st[N*10],top,tms[N*10]; void build(int id){ int u=rt[id],vsiz=use[id].size(); K=3; lis[1]=u; lis[2]=side[u][1]; lis[3]=side[u][2]; for(int i=0;i<vsiz;i++) lis[++K]=use[id][i]; sort(lis+1,lis+1+K); K=unique(lis+1,lis+1+K)-lis-1; sort(lis+1,lis+1+K,cmp); for(int i=1;i<=K;i++) newid[lis[i]]=++cnt,tms[lis[i]]=id; if(K>1){ st[1]=lis[1]; st[2]=lis[2]; top=2; for(int i=3;i<=K;i++){ int now=lis[i],lca=getLca(now,st[top]); while(1){ if(dep[lca]>=dep[st[top-1]]){ if(tms[lca]!=id) newid[lca]=++cnt,tms[lca]=id; addEdge(newid[lca],newid[st[top]],dep[st[top]]-dep[lca],H); addEdge(newid[st[top]],newid[lca],dep[st[top]]-dep[lca],H); top--; if(st[top]!=lca) st[++top]=lca; break; } addEdge(newid[st[top-1]],newid[st[top]],dep[st[top]]-dep[st[top-1]],H); addEdge(newid[st[top]],newid[st[top-1]],dep[st[top]]-dep[st[top-1]],H); top--; } if(st[top]!=now) st[++top]=now; } for(;top>1;top--){ addEdge(newid[st[top]],newid[st[top-1]],dep[st[top]]-dep[st[top-1]],H); addEdge(newid[st[top-1]],newid[st[top]],dep[st[top]]-dep[st[top-1]],H); } } for(int i=1;i<=K;i++) tree[id][lis[i]]=newid[lis[i]]; } void dfs(int u,int fa,ll dis){ if(dis>far[0]) far[0]=dis, far[1]=u; for(int i=H[u],v;i;i=g[i].next) if((v=g[i].v)!=fa) dfs(v,u,dis+g[i].w); } int main(){ scanf("%d%d",&n,&m); bas=((int)log2(n))+1; for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y), addEdge(x,y,1,ho),addEdge(y,x,1,ho); preDfs(1,0,1); for(int i=1,x;i<=m;i++) scanf("%d",&rt[i]); for(int i=1,a,b,c,d;i<m;i++){ scanf("%d%d%d%d",&a,&b,&c,&d); waitedge[i]=WaitEdge(a,b,c,d); use[a].push_back(b); use[c].push_back(d); } for(int i=1;i<=m;i++) build(i); for(int i=1;i<m;i++){ int a,b,c,d,x,y; waitedge[i].get(a,b,c,d); x=tree[a][b]; y=tree[c][d]; addEdge(x,y,1,H); addEdge(y,x,1,H); } dfs(tree[1][rt[1]],0,1); int t=far[1]; far[0]=far[1]=0; dfs(t,0,1); printf("%lld\n",far[0]); return 0; }
奇妙代码
相关文章推荐
- 【2016北京集训测试赛(七)】自动机 (思考题)
- 【2016北京集训测试赛(十)】 Azelso (期望DP)
- 【2016北京集训测试赛(二)】 thr (树形DP)
- 【2016北京集训测试赛(八)】 crash的数列 (思考题)
- 【2016北京集训测试赛(十六)】 River (最大流)
- 2016暑假集训7.27 链表 数据结构上机测试1:顺序表的应用
- uoj 279: [清华集训2016]温暖会指引我们前行
- [2016实习] 摩根大通-量化金融-北京
- CCNU ACM 2016夏季集训·day3比赛
- UOJ275 [清华集训2016] 组合数问题 【Lucas定理】【数位DP】
- 2017省选前北京集训总结
- XYNU—ACM暑假集训第二次测试
- 软件测试管理高级研修班(3天精品班,中国北京 2015.12.25~27)
- 腾讯2016测试开发岗笔试题--数组中出现次数超过一半的数字
- 第一届(2016)中国Meteor技术峰会 开发者交流会[北京][免费]
- 【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳
- 【硬件测试】华为2016校招·硬件技术工程师机考试题
- JZOJ4859. 【NOIP2016提高A组集训第7场11.4】连锁店
- 转自【柳永法】SQL统计:从北京到天津的与从天津到北京的汇总到一起 常用sql语句 SQL Server 生成版权信息及测试环境信息
- JZOJ4869【NOIP2016提高A组集训第9场11.7】平均数