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\n"::"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\n",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\n"::"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\n",doit());
131     return 0;
132 }
View Code

 

posted @ 2017-11-07 21:49  鲸头鹳  阅读(136)  评论(0编辑  收藏  举报