COJ 0349 WZJ的旅行(五)

WZJ的旅行(五)
难度级别:E; 运行时间限制:3000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

WZJ又要去旅行了T^T=0。幻想国由N个城市组成,由于道路翻修,只有N-1条双向道路可以通行,第i条双向道路从ui连接到vi,距离为wi。但这N-1条道路竟然连接了整个国家,每两个城市之间都有一条道路!

设d(a,b)表示a城市到b城市的距离(a<b)。WZJ想知道前k大的d(a,b)的值请你告诉他结果。

输入
第一个为两个正整数N,k。
接下来N-1行每行为三个正整数ui,vi,wi。  
输出
输出前k大的d(a,b)值,每个一行。
输入示例
5 10
1 2 1
1 3 2
2 4 3
2 5 4
输出示例
7
7
6
5
4
4
3
3
2
1
其他说明
1<=N<=50000,1<=k<=Min(300000,N*(N-1)/2)
1<=ui,vi<=N
1<=wi<=1000 

题解:点分治套一个超级钢琴耶,先将一个点能够到的位置用l,r数组记录下来(意会一下“够到”。。。),然后问题变为超级钢琴。。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstring>
 7 #define PAU putchar(' ')
 8 #define ENT putchar('
')
 9 #define CH for(int d=0;d<2;d++)if(ch[d])
10 #define lson x->ch[0],L,M
11 #define rson x->ch[1],M+1,R
12 using namespace std;
13 const int maxn=500000+10,maxnode=3000000+10,maxm=1000000+10,maxt=maxn*20,inf=-1u>>1;
14 struct ted{int x,y,w;ted*nxt;}adj[maxm],*fch[maxn],*ms=adj;
15 void add(int x,int y,int w){
16     *ms=(ted){x,y,w,fch[x]};fch[x]=ms++;
17     *ms=(ted){y,x,w,fch[y]};fch[y]=ms++;
18     return;
19 }
20 int CG,size,siz[maxn],f[maxn],l[maxt],r[maxt],t[maxt],ln,rn,tot;bool vis[maxn];
21 void findcg(int x,int fa){
22     siz[x]=1;int mxs=0;
23     for(ted*e=fch[x];e;e=e->nxt){
24         int v=e->y;if(v!=fa&&!vis[v]){
25             findcg(v,x);siz[x]+=siz[v];mxs=max(mxs,siz[v]);
26         }
27     }f[x]=max(mxs,size-siz[x]);if(f[x]<f[CG])CG=x;return;
28 }
29 void dfs(int x,int fa,int dis){
30     siz[x]=1;l[++tot]=ln;r[tot]=rn;t[tot]=dis;
31     for(ted*e=fch[x];e;e=e->nxt){
32         int v=e->y;if(v!=fa&&!vis[v])dfs(v,x,dis+e->w),siz[x]+=siz[v];
33     }return;
34 }
35 void solve(int x){
36     vis[x]=true;bool flag=true;
37     for(ted*e=fch[x];e;e=e->nxt){
38         int v=e->y;if(!vis[v]){
39             if(flag)flag=false,ln=rn=++tot;
40             dfs(v,x,e->w);rn=tot;
41         }
42     }
43     for(ted*e=fch[x];e;e=e->nxt){
44         int v=e->y;if(!vis[v]){
45             f[CG=0]=size=siz[v];findcg(v,x);solve(CG);
46         }
47     }return;
48 }
49 struct node{
50     node*ch[2];int p,v;node(){v=-inf;}
51     void update(){v=-inf;CH{if(v<ch[d]->v)p=ch[d]->p,v=ch[d]->v;}return;}
52 }seg[maxnode],*nodecnt=seg,*root;int n,k,ql,qr,_p,_v;
53 void build(node*&x=root,int L=1,int R=tot){
54     x=nodecnt++;int M=L+R>>1;if(L==R)x->p=M,x->v=t[M];
55     else build(lson),build(rson),x->update();return;
56 }
57 void query(node*x=root,int L=1,int R=tot){
58     if(ql<=L&&R<=qr){
59         if(_v<x->v)_v=x->v,_p=x->p;
60     }else{int M=L+R>>1;
61         if(ql<=M)query(lson);if(qr>M)query(rson);
62     }return;
63 }
64 struct info{int x,L,R,t;};
65 bool operator<(const info&a,const info&b){return t[a.t]+t[a.x]<t[b.t]+t[b.x];}
66 priority_queue<info>Q;
67 inline int read(){
68     int x=0,sig=1;char ch=getchar();
69     for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0;
70     for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
71     return sig?x:-x;
72 }
73 inline void write(long long x){
74     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
75     int len=0;long long buf[15];while(x)buf[len++]=x%10,x/=10;
76     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
77 }
78 void init(){
79     n=read();k=read();int x,y;
80     for(int i=1;i<n;i++)x=read(),y=read(),add(x,y,read());
81     f[CG=0]=size=n;findcg(1,0);solve(CG);
82     build();
83     for(int i=1;i<=tot;i++)if(l[i]){
84         ql=l[i];qr=r[i];_v=-inf;query();Q.push((info){i,l[i],r[i],_p});
85     }
86     for(int i=1;i<=k;i++){
87         info a=Q.top();Q.pop();write(t[a.x]+t[a.t]);ENT;
88         if(a.L<a.t){ql=a.L;qr=a.t-1;_v=-inf;query();Q.push((info){a.x,a.L,a.t-1,_p});}
89         if(a.t<a.R){ql=a.t+1;qr=a.R;_v=-inf;query();Q.push((info){a.x,a.t+1,a.R,_p});}
90     }
91     return;
92 }
93 void work(){
94     return;
95 }
96 void print(){
97     return;
98 }
99 int main(){init();work();print();return 0;}
原文地址:https://www.cnblogs.com/chxer/p/4709960.html