zoukankan      html  css  js  c++  java
  • JZYZOJ1454 NOIP2015 D2T3_运输计划 二分 差分数组 lca tarjan 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1454

    从这道题我充分认识到我的脑子里好多水orz。

    如果知道了这个要用二分和差分写,就没什么思考上的难点了(屁咧你写了一个下午)。

    下面讲述一下我写这道题的辛酸历程:

    我最开始写了个树链剖分+线段树+二分+差分数组,tle了一个点,这完全搞不懂啊,什么鬼啊,为什么啊,不然你告诉我怎么写啊。

    然后我去找了a了此题的Lcentury大神,然后他告诉我:“这个题要用tarjan求lca啊,都什么年代了还用树链剖分,tanjan快啊,你这肯定要超时的。”然后我就信了Lcentury大神的邪学了一波tanjan。

    我还很奇怪,tanjan怎么求两点之间距离啊???等到我辛辛苦苦读了一遍tanjan求两点距离的写法之后,狂喷凌霄血,原来只要找到lca一减就出来了,所以说树链剖分找lca是不会tle的,tle是因为我多加了一个sb线段树。

    所以我两种都写了一遍[二哈],事实证明两种方案速度的确没有差很多。。。大数据一个是2609ms一个是2640ms。

    下面展示我的两个代码(mdzz),就当mark模板了。

    tanjan

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<iostream>
      6 using namespace std;
      7 #define lc x*2
      8 #define rc x*2+1
      9 const int maxn=300010;
     10 int n,m;
     11 struct nod{
     12     int next,y,v;
     13 }e[maxn*2];
     14 int head[maxn]={},tot=0;
     15 struct wtf{
     16     int x,y,fa,v;
     17 }a[maxn];
     18 struct node{
     19     int y,id,next;
     20 }d[maxn*2];
     21 int lin[maxn]={};
     22 int fa[maxn]={};
     23 int f[maxn]={};
     24 int cnt,ned;
     25 int vis[maxn]={};
     26 int dis[maxn]={};
     27 inline void init(int x,int y,int v){
     28     e[++tot].y=y;
     29     e[tot].v=v;
     30     e[tot].next=head[x];
     31     head[x]=tot;
     32 }
     33 
     34 inline void insert(int x,int y,int id){
     35     d[++tot].y=y;
     36     d[tot].id=id;
     37     d[tot].next=lin[x];
     38     lin[x]=tot;
     39 }
     40 int read(){
     41     char ch=getchar();int x=0,f=1;
     42     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
     43     while(ch<='9'&&ch>='0'){x*=10;x+=ch-'0';ch=getchar();}
     44     return x*f;
     45 }
     46 int find(int x){
     47     if(f[x]==-1)
     48         return x;
     49     return f[x]=find(f[x]);
     50 }
     51 void merge(int u,int v){
     52     int x=find(u);
     53     int y=find(v);
     54     if(x!=y) f[x]=y;
     55 }
     56 void tarj(int x){
     57     int y,v;
     58     fa[x]=x;
     59     vis[x]=1;
     60     for(int i=head[x];i;i=e[i].next){
     61         y=e[i].y;v=e[i].v;
     62         if(vis[y])continue;
     63         dis[y]=dis[x]+v;
     64         tarj(y);
     65         merge(x,y);
     66         fa[find(x)]=x;
     67     }
     68     for(int i=lin[x];i;i=d[i].next){
     69         y=d[i].y;
     70         if(vis[y])
     71             a[d[i].id].fa=fa[find(y)];
     72     }
     73 }
     74 bool mmp(wtf aa,wtf bb){
     75     return aa.v>bb.v;
     76 }
     77 void dfs3(int x,int pa,int val){
     78     int y,v;
     79     for(int i=head[x];i;i=e[i].next){
     80         y=e[i].y;v=e[i].v;
     81         if(y==pa)continue;
     82         dfs3(y,x,v);
     83         vis[x]+=vis[y];
     84     }
     85 //    cout<<ned<<vis[x]<<val<<x<<endl;
     86     if(vis[x]==ned)cnt=max(cnt,val);
     87 }
     88 inline bool check(int x){
     89     cnt=0;
     90     memset(vis,0,sizeof(vis));
     91     for(int i=1;i<=m;i++){
     92         if(a[i].v>x){
     93             vis[a[i].x]++;
     94             vis[a[i].y]++;
     95             vis[a[i].fa]-=2;
     96         }
     97         else{
     98             ned=i-1;
     99             break;
    100         }
    101         if(i==m)ned=m;
    102     }
    103     dfs3(1,1,0);
    104     if(a[1].v-cnt<=x)return 1;
    105     else return 0;
    106 }
    107 inline int doit(){
    108     int l=0,r=a[1].v;
    109     while(l<r){
    110         int mid=(l+r)/2;
    111         if(check(mid))r=mid;
    112         else l=mid+1;
    113     }
    114     return l;
    115 }
    116 int main(){
    117     //freopen("wtf.in","r",stdin);
    118     int size=128<<20;
    119     char *p=(char*)malloc(size)+size;
    120     __asm__("movl %0,%%esp
    "::"r"(p));
    121     n=read();m=read();
    122     int x,y,v;
    123     for(int i=1;i<n;i++){
    124         x=read();y=read();v=read();
    125         init(x,y,v);init(y,x,v);
    126     }tot=0;
    127     for(int i=1;i<=m;i++){
    128         a[i].x=read();a[i].y=read();
    129         insert(a[i].x,a[i].y,i);
    130         insert(a[i].y,a[i].x,i);
    131     }memset(f,-1,sizeof(f));
    132     tarj(1);
    133     for(int i=1;i<=m;i++){
    134         a[i].v=dis[a[i].x]+dis[a[i].y]-dis[a[i].fa]*2;
    135     }
    136     sort(a+1,a+1+m,mmp);
    137     printf("%d
    ",doit());
    138     return 0;
    139 }
    View Code

    树链剖分

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<iostream>
      6 using namespace std;
      7 #define lc x*2
      8 #define rc x*2+1
      9 const int maxn=300010;
     10 int n,m;
     11 struct nod{
     12     int next,y,v;
     13 }e[maxn*2];
     14 int head[maxn]={},tot=0;
     15 int dep[maxn]={},fa[maxn]={},kid[maxn]={};
     16 int top[maxn]={};
     17 int dis[maxn]={};
     18 inline void init(int x,int y,int v){
     19     e[++tot].y=y;
     20     e[tot].v=v;
     21     e[tot].next=head[x];
     22     head[x]=tot;
     23 }
     24 int dfs(int x,int pa){
     25     int y,val,v,tsn=0,hug=0;
     26     dep[x]=dep[pa]+1;
     27     fa[x]=pa;
     28     for(int i=head[x];i;i=e[i].next){
     29         y=e[i].y;v=e[i].v;
     30         if(y==pa)continue;
     31         dis[y]=dis[x]+v;
     32         val=dfs(y,x);
     33         if(val>hug)hug=val,kid[x]=y;
     34         tsn+=val;
     35     }
     36     tsn+=1;
     37     return tsn;
     38 }
     39 void dfs1(int x,int pa){
     40     int y,v;
     41     top[x]=pa;
     42     if(kid[x])dfs1(kid[x],pa);
     43     for(int i=head[x];i;i=e[i].next){
     44         y=e[i].y;v=e[i].v;
     45         if(y==fa[x]||y==kid[x])continue;
     46         dfs1(y,y);
     47     }
     48 }
     49 int getit(int x,int y){
     50     int xx=top[x],yy=top[y];
     51     while(xx!=yy){
     52         if(dep[xx]<dep[yy]){
     53             swap(xx,yy);
     54             swap(x,y);
     55         }
     56         x=fa[xx];xx=top[x];
     57     }
     58     if(dep[x]>dep[y])return y;
     59     return x;
     60 }
     61 int read(){
     62     char ch=getchar();int x=0,f=1;
     63     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
     64     while(ch<='9'&&ch>='0'){x*=10;x+=ch-'0';ch=getchar();}
     65     return x*f;
     66 }
     67 struct wtf{
     68     int x,y,fa,v;
     69 }a[maxn];
     70 bool mmp(wtf aa,wtf bb){
     71     return aa.v>bb.v;
     72 }
     73 int cnt,ned;
     74 int vis[maxn]={};
     75 void dfs3(int x,int val){
     76     int y,v;
     77     for(int i=head[x];i;i=e[i].next){
     78         y=e[i].y;v=e[i].v;
     79         if(y==fa[x])continue;
     80         dfs3(y,v);
     81         vis[x]+=vis[y];
     82     }
     83     if(vis[x]==ned)cnt=max(cnt,val);
     84 }
     85 inline bool check(int x){
     86     cnt=0;
     87     memset(vis,0,sizeof(vis));
     88     for(int i=1;i<=m;i++){
     89         if(a[i].v>x){
     90             vis[a[i].x]++;
     91             vis[a[i].y]++;
     92             vis[a[i].fa]-=2;
     93         }
     94         else{
     95             ned=i-1;
     96             break;
     97         }
     98         if(i==m)ned=m;
     99     }
    100     dfs3(1,0);
    101     if(a[1].v-cnt<=x)return 1;
    102     else return 0;
    103 }
    104 inline int doit(){
    105     int l=0,r=a[1].v;
    106     while(l<r){
    107         int mid=(l+r)/2;
    108         if(check(mid))r=mid;
    109         else l=mid+1;
    110     }
    111     return l;
    112 }
    113 int main(){
    114     //freopen("wtf.in","r",stdin);
    115     int size=128<<20;
    116     char *p=(char*)malloc(size)+size;
    117     __asm__("movl %0,%%esp
    "::"r"(p));
    118     n=read();m=read();
    119     int x,y,v;
    120     for(int i=1;i<n;i++){
    121         x=read();y=read();v=read();
    122         init(x,y,v);init(y,x,v);
    123     }dfs(1,1);
    124     dfs1(1,1);
    125     for(int i=1;i<=m;i++){
    126         a[i].x=read();a[i].y=read();
    127         a[i].fa=getit(a[i].x,a[i].y);
    128         a[i].v=dis[a[i].x]+dis[a[i].y]-2*dis[a[i].fa];
    129     }sort(a+1,a+1+m,mmp);
    130     printf("%d
    ",doit());
    131     return 0;
    132 }
    View Code
  • 相关阅读:
    Xamarin Layout属性(转)
    Oracle基础
    tableViewNestTableView(tableView嵌套collectionView)
    抓包工具Fiddler的使用教程(五): 修改response的数据 .
    Web调试利器fiddler
    SQLServer光标
    SQLServer触发器
    web端功能测试总结(一)
    web功能测试
    test zlj
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7801297.html
Copyright © 2011-2022 走看看