码迷,mamicode.com
首页 > 其他好文 > 详细

SDOJ 3740 Graph

时间:2018-08-09 12:22:02      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:return   continue   范围   lse   name   算法   isp   one   lld   

8.9 t3

【描述】

给你一个图,一共有 N 个点,2*N-2 条有向边。
边目录按两部分给出
1、 开始的 n-1 条边描述了一颗以 1 号点为根的生成树,即每个点都可以由 1 号点

到达。
2、 接下来的 N-1 条边,一定是从 i 到 1(2<=i<=N)的有向边,保证每个点都能到

1
有 q 次询问:

1 x w :表示将第x条边的边权修改为w

2 u v :询问u到v的最短距离

【输入格式】

第一行是 2 个整数 N,Q,表示一共 N 个点 Q 次询问 接下来是 N-1 行,每行 3 个整数 U,V,W,表示了前 N-1 条边,u 到 v 的有向边 接下来 N-1 行,每行 3 个整数 U,V,W,描述了每个点到 1 号点的边,V==1 接下来是 Q 行,表示 Q 次修改与询问

【输出格式】

若干行,每行回答一次询问

【输入样例】

5 9
1 3 1
3 2 2
1 4 3
3 5 4
5 1 5
3 1 6
2 1 7
4 1 8
2 1 1
2 1 3
2 3 5
2 5 2
1  1 100
2 1 3
1 8 30
2 4 2
2 2 4

【输出样例】

0
1
4
8
100
132
10

【数据规模】 

20%数据 没有修改

30%数据 2<=N,Q<=1000 (其中有 10%数据没有修改)
100%数据 2<=N,Q<=100 000, 1 <=边权 <= 1000,000

 
----------------------------------------------------------------------------------------
 
这个题首先一看,20%没有修改.....大概可以写个LCA?
30% Q<=1000.......大概可以打个暴力?
 

以下正解

对于询问(u,v),分为两种情况
1.u为v的祖先,所以dis=dis[u]-dis[v];
2.u不是v的祖先 则 u 先到达 1 号点再到达 v 点。此时 u 必须先找到回到 1 的最短路(一定是自身直接回到 1 或通过以 u 为根子树的某点回到 1 )。且1号点到v点的路径唯一。
 
我们先做dfs序 然后对每个点维护一个dist[i],dist[i]=根到节点距离+节点返回根距离

每个点记录第一次的dfs序st[i], 子树结束的 ed[i],在对于第 2 种情况是 min{dist[i]}-dis[u] + dis[v]
其中 i 是 u 的子树,dis[u]表示从 1  u的值

对于修改(x,w),也分为两种情况

1.当边 u->v 修改为 w,则 st[v]...ed[v] 增加 w- w’,w’表示 u->v 原来的值

2.当边 u->1 修改为 w:则 st[u]..st[u]增加 w-w’

 

当然暴力修改区间值肯定是会挂掉的ovo 怎么办?

当然是线段树啦

 

等一下 还要提一提查错

写线段树的时候一定要冷静 之前把 ans=min(ans,query(ql,qr,lc));直接没写min的比较....

以后先查主函数的逻辑和调用有没有问题,不能一直纠缠改算法和数据结构

还要注意数据范围和long long 与 int之间的选择,不能全部用long long 

 

记得开大数组范围!!!

记得开大数组范围!!!

记得开大数组范围!!!

 

贴一下代码~

 

技术分享图片
  1 #include<queue>
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cmath>
  5 #define N 400010
  6 using namespace std;
  7 #define LL long long
  8 int st[N],ed[N],rev[N],idfn=0;
  9 LL dist[N];
 10 int x[N],y[N],z[N];
 11 int n,Q;
 12 struct node
 13 {
 14     int u,v,w,nxt;
 15 }e[N*2];
 16 int first[N],cnt;
 17 void ade(int u,int v,int w)
 18 {
 19     e[++cnt].nxt=first[u];first[u]=cnt;
 20     e[cnt].v=v;e[cnt].u=u;e[cnt].w=w;
 21 }
 22 //segment tree
 23 
 24 #define lc (p<<1)
 25 #define rc (p<<1|1)
 26 LL a[N],mn[N*2];
 27 struct Node
 28 {
 29     int l,r; LL lazy;
 30 }T[N*4];
 31 void pushnow(LL p,LL v)
 32 {
 33     T[p].lazy+=v;
 34     mn[p]+=v;
 35     return;
 36 }
 37 void pushdown(LL p,LL m)
 38 {
 39     if(T[p].lazy)
 40     {
 41         T[lc].lazy+=T[p].lazy;
 42         T[rc].lazy+=T[p].lazy;
 43         mn[lc]+=T[p].lazy;
 44         mn[rc]+=T[p].lazy;
 45         T[p].lazy=0;
 46     }
 47 }
 48 void pushup(int  p)
 49 {
 50     mn[p]=min(mn[lc],mn[rc]);
 51 }
 52 void build(int p,int l,int r)//建树
 53 {
 54     T[p].lazy=0;
 55     T[p].l=l;T[p].r=r;
 56     if(l==r)
 57     {
 58         mn[p]=dist[l];
 59         return;
 60     }
 61     int mid=(l+r)>>1;
 62     build(lc,l,mid);
 63     build(rc,mid+1,r);
 64     pushup(p);
 65 }
 66 void update(int ql,int qr,int v,int p)//向上维护 L=ql
 67 {
 68     if(ql>qr) return;
 69     if(ql<=T[p].l&&T[p].r<=qr)
 70     {
 71         pushnow(p,v);//!!!!!!
 72         return;
 73     }
 74     int mid=(T[p].l+T[p].r)>>1;
 75     pushdown(p,T[p].r-T[p].l+1);
 76     if(ql<=mid)
 77         update(ql,qr,v,lc);
 78     if(qr>mid)
 79         update(ql,qr,v,rc);
 80     pushup(p);
 81 }
 82 LL query(int ql,int qr,int p)
 83 {
 84     if(ql<=T[p].l&&qr>=T[p].r) return mn[p];
 85     int mid=(T[p].l+T[p].r)>>1;
 86     pushdown(p,T[p].r-T[p].l+1);
 87     LL ans=0x3f3f3f3f;
 88     if(ql<=mid) ans=min(ans,query(ql,qr,lc));//!!!!
 89     if(qr>mid) ans=min(ans,query(ql,qr,rc));//!!!!
 90     //pushup(p);
 91     return ans;
 92 }
 93 void getdfn(int rt,int fa,long long w)
 94 {
 95     st[rt]=++idfn;
 96     dist[st[rt]]=w+rev[rt];//算dist[i]值
 97     for(int i=first[rt];i;i=e[i].nxt)
 98     {
 99         if(e[i].v==fa) continue;
100         getdfn(e[i].v,rt, w+e[i].w);
101     }
102     ed[rt]=idfn;
103 }
104 //LCA
105 int h[N],dep[N],fa[N][25];
106 void dfs(int u)
107 {
108     for(int i=1;i<=21;i++) fa[u][i]=fa[fa[u][i-1]][i-1];
109     for(int i=first[u];i;i=e[i].nxt)
110     {
111         int v=e[i].v;
112         if(v!=fa[u][0])
113         {
114             fa[v][0]=u;
115             h[v]=h[u]+1;
116             dep[v]=dep[u]+1;
117             dfs(v);
118         }
119     }
120 }
121 int lca(int u,int v)
122 {
123     if(h[u]<h[v]) return lca(v,u);
124     int i,d=h[u]-h[v];
125     for(i=0;i<=20;i++)
126         if((d>>i)&1) u=fa[u][i];
127     
128     if(u==v) return u;
129     for(i=20;i>=0;i--)
130     {
131         if(fa[u][i]!=fa[v][i])
132         {
133             u=fa[u][i];
134             v=fa[v][i];
135         }
136     }
137     return fa[u][0];
138 }
139 int main()
140 {
141     scanf("%d%d",&n,&Q);
142     for(int i=1;i<=2*(n-1);i++)
143     {
144         scanf("%d%d%d",&x[i],&y[i],&z[i]);
145         if(i<=n-1) ade(x[i],y[i],z[i]);
146         else rev[x[i]]=z[i];//cout<<2<<endl;
147     }//cout<<"x"<<endl;
148     getdfn(1,0,0);
149     //cout<<"x"<<endl;
150     dfs(1);
151     build(1,1,idfn);
152     int op,a,b,u,v;
153     for(int i=1;i<=Q;i++)
154     {
155         scanf("%d",&op);
156         if(op==1)
157         {
158             scanf("%d%d",&a,&b);
159             if(a>=n)
160             {
161                 update(st[x[a]],st[x[a]],b-rev[x[a]],1);
162                 rev[x[a]] = b;
163             }
164             else
165             {
166                 update(st[y[a]],ed[y[a]],b-z[a] ,1);
167                 z[a]=b;
168             }
169         }
170         if(op==2)
171         {
172             scanf("%d%d",&u,&v);
173             if(lca(u,v)==u)
174             {
175                 long long du=query(st[u],st[u],1)-rev[u];
176                 long long dv=query(st[v],st[v],1)-rev[v];
177                 printf("%lld\n", dv - du);
178             }
179             else
180             {
181                 LL mnDist=query(st[u],ed[u],1)-query(st[u],st[u],1) + rev[u];
182                 LL dv=query(st[v],st[v],1)-rev[v];
183                 printf("%lld\n",mnDist+dv);
184             }
185         }
186     }
187     return 0;
188 }/*
189 5 9
190 1 3 1
191 3 2 2
192 1 4 3
193 3 5 4
194 5 1 5
195 3 1 6
196 2 1 7
197 4 1 8
198 2 1 1
199 2 1 3
200 2 3 5
201 2 5 2
202 1 1 100
203 2 1 3
204 1 8 30
205 2 4 2
206 2 2 4
207 */
233333

 

SDOJ 3740 Graph

标签:return   continue   范围   lse   name   算法   isp   one   lld   

原文地址:https://www.cnblogs.com/kylara/p/9447744.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!