• COJ 0288 路径(2015升级版)


    路径(2015升级版)
    难度级别:D; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
    试题描述
    WZJ在生日当天决定在他的领地举行一场马拉松比赛,他的领地有N座城市,是通过道路相连组成了一个N-1条边的无向无环图。每条边由ai连到bi,距离为ci。WZJ决定选取两个城市分别为起点和终点,举行比赛。比赛时按这两个城市间的最短距离进行比赛。WZJ想选出一条尽量长的路径,但由于资金限制,路径长最多不能超过k。你能帮帮他吗?
    输入
    第一行为两个正整数N,k,表示N个城市,最长距离为K。
    接下来N-1行为ai,bi,ci,表示有一条边从ai到bi,距离为ci。
    输出
    输出路径在小于k的情况下的最长长度。
    输入示例
    5 7
    1 2 3
    1 3 4
    4 5 7
    4 2 2
    输出示例
    7
    其他说明
    1<=N<=50000 
    1<=ai,bi<=N
    1<=ci<=k<=10^9
    起点为2,终点为3.
    放心,不是O(nlog^2n)是过不了的!

    题解:点分治,看好那个find函数。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #include<ctime>
      8 #define PAU putchar(' ')
      9 #define ENT putchar('
    ')
     10 #define CH for(int d=0;d<2;d++)if(ch[d])
     11 using namespace std;
     12 const int maxn=50000+10,maxm=100000+10,inf=-1u>>1;
     13 struct node{
     14     node*ch[2];int r,siz,v;
     15     void init(){r=rand();siz=1;ch[0]=ch[1]=NULL;return;}
     16     void update(){siz=1;CH{siz+=ch[d]->siz;}return;}
     17 }treap[maxn],*nodecnt=treap,*root;queue<node*>R;
     18 void del(node*&x){R.push(x);x=NULL;return;}
     19 void deltree(node*&x){
     20     if(!x)return;deltree(x->ch[0]);deltree(x->ch[1]);del(x);return;
     21 }
     22 node*newnode(){
     23     node*k;if(R.empty())k=nodecnt++;else k=R.front(),R.pop();k->init();return k;
     24 }
     25 void rotate(node*&x,int d){
     26     node*k=x->ch[d^1];x->ch[d^1]=k->ch[d];k->ch[d]=x;x->update();k->update();x=k;return;
     27 }
     28 void insert(node*&x,int v){
     29     if(!x)x=newnode(),x->v=v;
     30     else{int d=v>x->v;insert(x->ch[d],v);
     31         if(x->r<x->ch[d]->r)rotate(x,d^1);else x->update();
     32     }return;
     33 }
     34 void print(node*x){
     35     if(!x)return;print(x->ch[0]);printf("%d ",x->v);print(x->ch[1]);return;
     36 }
     37 int find(node*x,int v){
     38     if(!x)return 0;
     39     if(v==x->v)return v;
     40     if(v>x->v)return max(x->v,find(x->ch[1],v));
     41     return find(x->ch[0],v);
     42 }
     43 struct ted{int x,y,w;ted*nxt;}adj[maxm],*fch[maxn],*ms=adj;
     44 void add(int x,int y,int w){
     45     *ms=(ted){x,y,w,fch[x]};fch[x]=ms++;
     46     *ms=(ted){y,x,w,fch[y]};fch[y]=ms++;
     47     return;
     48 }
     49 int ans,k,t[maxn],cnt,f[maxn],CG,siz[maxn],size;bool vis[maxn];
     50 void findcg(int x,int fa){
     51     siz[x]=1;int mxs=0;
     52     for(ted*e=fch[x];e;e=e->nxt){
     53         int v=e->y;if(v!=fa&&!vis[v]){
     54             findcg(v,x);siz[x]+=siz[v];mxs=max(mxs,siz[v]);
     55         }
     56     }f[x]=max(mxs,size-siz[x]);if(f[x]<f[CG])CG=x;return;
     57 }
     58 void dfs(int x,int fa,int dis){
     59     siz[x]=1;t[cnt++]=dis;
     60     for(ted*e=fch[x];e;e=e->nxt){
     61         int v=e->y;if(v!=fa&&!vis[v])dfs(v,x,dis+e->w),siz[x]+=siz[v];
     62     }return;
     63 }
     64 void solve(int x){
     65     vis[x]=true;insert(root,0);
     66     for(ted*e=fch[x];e;e=e->nxt){
     67         int v=e->y;if(!vis[v]){
     68             cnt=0;dfs(v,x,e->w);
     69             for(int i=0;i<cnt&&t[i]<=k;i++)ans=max(ans,find(root,k-t[i])+t[i]);
     70             for(int i=0;i<cnt;i++)insert(root,t[i]);
     71         }
     72     }deltree(root);
     73     for(ted*e=fch[x];e;e=e->nxt){
     74         int v=e->y;if(!vis[v]){
     75             f[CG=0]=size=siz[v];findcg(v,x);solve(CG);
     76         }
     77     }return;
     78 }
     79 inline int read(){
     80     int x=0,sig=1;char ch=getchar();
     81     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
     82     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
     83     return x*=sig;
     84 }
     85 inline void write(int x){
     86     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
     87     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
     88     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
     89 }
     90 int n;
     91 void init(){
     92     srand(time(0));
     93     n=read();k=read();int x,y;
     94     for(int i=1;i<n;i++)x=read(),y=read(),add(x,y,read());
     95     f[CG=0]=size=n;findcg(1,0);solve(CG);write(ans);
     96     return;
     97 }
     98 void work(){
     99     return;
    100 }
    101 void print(){
    102     return;
    103 }
    104 int main(){init();work();print();return 0;}
    105 /*
    106 5 8
    107 1 2 2
    108 2 3 7
    109 1 4 3
    110 4 5 4
    111 */
  • 相关阅读:
    基于SPA的网页授权流程(微信OAuth2)
    用CSS3制作尖角标签按钮样式
    关于WebAPI跨域踩到的一点坑
    .net webapi跨域方法整理
    使用 JavaScript 截屏
    关于anguar2微信支付问题
    sql操作语句
    mysql5.7初始化密码报错 ERROR 1820 (HY000): You must reset your password using ALTER USER statement before
    linux上安装mysql5.7
    git 常用命令
  • 原文地址:https://www.cnblogs.com/chxer/p/4700244.html
Copyright © 2020-2023  润新知