发展城市 bzoj 3700

发展城市

【问题描述】

众所周知,Hzwer学长是一名高富帅,他打算投入巨资发展一些小城市。

Hzwer打算在城市中开N个宾馆,由于Hzwer非常壕,所以宾馆必须建在空中,但是这样就必须建立宾馆之间的连接通道。机智的Hzwer在宾馆中修建了N-1条隧道,也就是说,宾馆和隧道形成了一个树形结构。

Hzwer有时候会花一天时间去视察某个城市,当来到一个城市之后,Hzwer会分析这些宾馆的顾客情况。对于每个顾客,Hzwer用三个数值描述他:(S, T, V)表示该顾客这天想要从宾馆S走到宾馆T,他的速度是V。

Hzwer需要做一些收集一些数据,这样他就可以规划他接下来的投资。

其中有一项数据就是收集所有顾客可能的碰面次数。

每天清晨,顾客同时从S出发以V的速度前往T(注意S可能等于T),当到达了宾馆T的时候,顾客显然要找个房间住下,那么别的顾客再经过这里就不会碰面了。特别的,两个顾客同时到达一个宾馆是可以碰面的。同样,两个顾客同时从某宾馆出发也会碰面。

【输入格式】

第一行一个正整数T(1<=T<=20),表示Hzwer发展了T个城市,并且在这T个城市分别视察一次。

对于每个T,第一行有一个正整数N(1<=N<=10^5)表示Hzwer在这个城市开了N个宾馆。

接下来N-1行,每行三个整数X,Y,Z表示宾馆X和宾馆Y之间有一条长度为Z的隧道

再接下来一行M表示这天顾客的数量。

紧跟着M行每行三个整数(S, T, V)表示该顾客会从宾馆S走到宾馆T,速度为v

【输出格式】

对于每个T,输出一行,表示顾客的碰面次数。

【样例输入】

1

3

1 2 1

2 3 1

3

1 3 2

3 1 1

1 2 3

1

0

【样例输出】

2

0

【数据规模】

1<=T<=20   1<=N<=10^5   0<=M<=10^3   1<=V<=10^6   1<=Z<=10^3



题解:

主要算法:最近公共祖先(Lca);

题意就是求两两树上路径是否能在相交路径上相遇

求相交路径自然就要求出最近公共祖先

╰( ̄▽ ̄)╭为了卡常数,使用O(1)求Lca的方法(当然,某位dalao用了O(log2(n))的树剖,并真的好像跑得确实稍微快那么一点~~~)

首先处理出树的欧拉序列(就是把每个点入栈和出栈记录下来,那么两个点的Lca就是它们组成的区间中深度最小的点)

用Rmq处理区间最值和对应的点就好啦

有了Lca,两个点的距离自然好求

那么我们就解决了问题的子问题的子问题的两个子问题啦

先考虑如何求出在一条路径上与某个点距离最近的点,记为Closest(a,b,c)

假设我们要求出(a,b)路径上的距离c最近的点

记x=Lca(a,b),y=Lca(c,a),z=Lca(c,b)

首先如果c不在x的子树内,由于树上最近路径唯一,x就是在(a,b)路径上与c最近的点

否则如果y不为x,这说明c和a同时属于x某个孩子的子树,那么y就是最近点,z同理

再否则说明a,b,c分属x三个孩子的子树,那么x还是最近点

至此我们解决了求路径上与点最近的点的问题

我们再来考虑如何求出两条路径的交这个子问题(对,没错,上面那个就是子问题的子问题,也是问题的子问题)

如果两条路径有交,那么第一条路径的两个点与第一条路径的两个最近点组成的路径必定与第二条路径的两个点与第一条路径的两个最近点组成的路径相等

有点点长(不是打错了(废话好多(自己吐槽是什么鬼))),冗长的自然语言啊

记两条路径为(a,b)和(c,d)

记abc为Close(a,b,c),其他同理

那么(abc,abd)=(cda,cdb)(这是无序的)

又一个问题解决了

最后考虑是否相遇

起点相同啊,没有相交路径啊,相交路径只有一个点啊,这些判一判就好啦

设两个人为x,y

设相交路径为u,v

设两条路径(两个人)的起点、终点为sx,tx,sy,ty

记Time(x,y)为x为起点,y为终点,以以x为起点的人的速度为速度所需的时间(再次重申没有打错)

求相遇当然要判断同向异向,判断的话考虑Closest(u,v,sx)是否等于Closest(u,v,sy),两个的含义分别是求两个点在相交路径上的起点,剩下的就显而易见了

为了方便,取u为x在(u,v)上的起点

异向的话只要满足一个在到达起点时另一个还未达到终点,那么它们必定相遇,判断就是Time(sx,u)<=Time(sy,u)且Time(sy,v)<=Time(sx,v)

同向的话只要满足先到达起点的后到达终点就行了,判断就看代码实现吧

求时间的话要用double啥的

由于我们只要求大小关系,交叉相乘即可

至此我们结束了整个问题(os:怎么这么长~~~~~~)

其实我是%了黄学长代码的<(* ̄▽ ̄*)/(那你还bb这么多)

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cstdio>
  6 #include<cmath>
  7 using namespace std;
  8 const int logn = 19;
  9 const int maxn = 300233;
 10 int lea[maxn][logn], dot[maxn][logn];
 11 int num, pos[maxn], dfn[maxn], dep[maxn];
 12 long long dis[maxn];
 13 int tot, nex[maxn], fir[maxn], ver[maxn], val[maxn];
 14 int powe[logn], loga[maxn];
 15 int T;
 16 int n, m;
 17 int x, y, z;
 18 int ans;
 19 int s[maxn], t[maxn], vel[maxn];
 20 struct couple
 21 {
 22     int x, y;
 23 };
 24 inline void Scan(int &x)
 25 {
 26     char c;
 27     bool o = false;
 28     while((c = getchar()) < ‘0‘ || c > ‘9‘)
 29         if(c == ‘-‘) o = true;
 30     x = c - ‘0‘;
 31     while((c = getchar()) >= ‘0‘ && c <= ‘9‘)
 32         x = x * 10 + c - ‘0‘;
 33     x = (o) ? -x : x;
 34 }
 35 inline void Clear()
 36 {
 37     tot = num = ans = 0;
 38     for(int i = 1; i <= n; ++i) fir[i] = 0;
 39 }
 40 inline void Ins(int x, int y, int z)
 41 {
 42     nex[++tot] = fir[x];
 43     fir[x] = tot;
 44     ver[tot] = y;
 45     val[tot] = z;
 46 }
 47 inline void Table()
 48 {
 49     powe[0] = 1;
 50     loga[1] = 0;
 51     for(int i = 1; i < logn; ++i) powe[i] = powe[i - 1] << 1, loga[powe[i]] = 1;
 52     for(int i = 1; i < maxn; ++i) loga[i] += loga[i - 1];
 53 }
 54 inline void Rmq()
 55 {
 56     for(int i = 1; i <= num; ++i)
 57     {
 58         dot[i][0] = dfn[i];
 59         lea[i][0] = dep[dfn[i]];
 60     }
 61     for(int j = 1; j <= loga[num] + 1; ++j)
 62         for(int i = 1; i <= num; ++i)
 63         {
 64             int k = i + powe[j - 1];
 65             if(k >= num) continue;
 66             if(lea[i][j - 1] < lea[k][j - 1])
 67             {
 68                 lea[i][j] = lea[i][j - 1];
 69                 dot[i][j] = dot[i][j - 1];
 70             }
 71             else
 72             {
 73                 lea[i][j] = lea[k][j - 1];
 74                 dot[i][j] = dot[k][j - 1];
 75             }
 76         }
 77 }
 78 inline int Lca(int x, int y)
 79 {
 80     x = pos[x], y = pos[y];
 81     if(x > y) swap(x, y);
 82     int len = loga[y - x + 1];
 83     int mid = y - powe[len] + 1;
 84     if(lea[x][len] < lea[mid][len]) return dot[x][len];
 85     return dot[mid][len];
 86 }
 87 inline long long Dis(int x, int y)
 88 {
 89     return dis[x] + dis[y] - (dis[Lca(x, y)] << 1);
 90 }
 91 void Dfs(int u, int f)
 92 {
 93     pos[u] = ++num;
 94     dfn[num] = u;
 95     for(int i = fir[u]; i; i = nex[i])
 96     {
 97         int v = ver[i];
 98         if(v == f) continue;
 99         dep[v] = dep[u] + 1;
100         dis[v] = dis[u] + val[i];
101         Dfs(v, u);
102         dfn[++num] = u;
103     }
104 }
105 inline int Close(int a, int b, int c)
106 {
107     int x = Lca(a, b);
108     if(x != Lca(x, c)) return x;
109     int y = Lca(a, c);
110     if(x != y) return y;
111     int z = Lca(b, c);
112     if(x != z) return z;
113     return x;
114 }
115 inline couple Path(int a, int b, int c, int d)
116 {
117     int abc = Close(a, b, c);
118     int abd = Close(a, b, d);
119     int cda = Close(c, d, a);
120     int cdb = Close(c, d, b);
121     if(abc > abd) swap(abc, abd);
122     if(cda > cdb) swap(cda, cdb);
123     if(abc == cda && abd == cdb) return (couple) {abc, abd};
124     return (couple) {-1, -1};
125 }
126 inline bool Meet(int x, int y)
127 {
128     if(s[x] == s[y]) return true;
129     couple z = Path(s[x], t[x], s[y], t[y]);
130     int u = z.x, v = z.y;
131     if(u < 0) return false;
132     if(u == v) return Dis(s[x], u) * vel[y] == Dis(s[y], u) * vel[x];
133     if(Close(u, v, s[x]) == v) swap(u, v);
134     if(Close(u, v, s[x]) != Close(u, v, s[y]))
135     {
136         bool fa = Dis(s[x], u) * vel[y] <= Dis(s[y], u) * vel[x];
137         bool fb = Dis(s[x], v) * vel[y] >= Dis(s[y], v) * vel[x];
138         return fa && fb;
139     }
140     long long a = Dis(s[x], u) * vel[y];
141     long long b = Dis(s[y], u) * vel[x];
142     if(a == b) return true;
143     if(a > b) swap(x, y);
144     return Dis(s[x], v) * vel[y] >= Dis(s[y], v) * vel[x];
145 }
146 int main()
147 {
148     memset(lea, 127, sizeof(lea));
149     Table();
150     Scan(T);
151     while(T--)
152     {
153         Clear();
154         Scan(n);
155         for(int i = 1; i < n; ++i)
156         {
157             Scan(x), Scan(y), Scan(z);
158             Ins(x, y, z);
159             Ins(y, x, z);
160         }
161         Dfs(1, 0);
162         Rmq();
163         Scan(m);
164         for(int i = 1; i <= m; ++i) Scan(s[i]), Scan(t[i]), Scan(vel[i]);
165         for(int i = 1; i <= m; ++i)
166             for(int j = i + 1; j <= m; ++j)
167                 ans += Meet(i, j);
168         printf("%d\n", ans);
169     }
170 }
时间: 2024-10-12 02:55:28

发展城市 bzoj 3700的相关文章

多校第八场:图论出度

HDU 4948 这题比赛的时候遗憾了,我看了这道题,然后觉得挺简单的. 刚开始一看题上,想到的就是拓扑排序,然后脑子想啊想--感觉就是拓扑排序的逆序,然后发现挺水的-- 因为说了要想发展某个城市的话,就必须有另一个城市作为它发展的前提,即城市u->w这样连边,表示要想发展城市w,前提是u已经是发展过的城市了.那这样的话不是很简单嘛. 即统计出出度最多的就是第一个要发展的城市了,因为u->w这样连边可以看出算出出度最多的依次从大到小排序就行了. 哎呀,不过可惜了,因为看见没人交这题,然后也不敢

新华社受权发布“十三五”规划纲要 共分为20篇(

新华社受权发布"十三五"规划纲要 共分为20篇(全文/图表) 分享到: 539 2016-03-17 16:00:48字号:A- A A+来源:新华社 关键字:十三五规划全文 2016年,是中国全面建成小康社会决胜阶段的开局之年,也是推进结构性改革的攻坚之年.这一年,中国将在新的历史起点上大展宏图. 新华社将于今日下午播发<政府工作报告>和"十三五"规划纲要,其中,<政府工作报告>共分三个部分,约2万字,"十三五"规划纲要

多第八田间学校:几何+图论出度+模拟+找到规律

HDU 4946 pid=1002&cid=509" style="color:rgb(26,92,200); text-decoration:none; font-family:Tahoma; background-color:rgb(215,235,255)">Area of Mushroom 这题WA了7发才过,队友做的,然后一起debug了好久. 刚開始是没排序. 然后是在同一个位置的点没有处理好. 然后把这两个问题搞定就A了. #include <

中科燕园GIS外包团队(手机:13261043797 QQ:1216807928)致力于林业精耕细作

城市森林是城市中主要的生态服务功能景观元素,它对于改善城市环境.提供居民休闲游憩.满足身心健康需求.防灾御灾等生态系统服务的发挥具有不可代替的作用.居民可以方便地获取城市森林的“自然服务”是城市森林基本的功能要求,是市民生活质量的重要指标.根据<广州市林业和园林“十二五”发展规划>,广州于2011-2015年通过发展城市森林生态体系.林业产业体系.森林生态文化体系.林业支撑服务体系.园林建设工程体系.园林管理体系.园林支撑体系等7大体系.其中,ArcGIS强大的分析功能一直是该体系的重要技术支

Java学习有方法有捷径

很多人都想掌握一门技术,想学习Java开发,看中的不仅仅是广阔的行业发展前景,更是高薪的诱惑.具体要怎么做,才能在较短的时间内高效的掌握Java开发技术?笔者在此稍作梳理. 无论学习还是做任何事情前,都要对所所要着手的事情有个大致的了解,学习Java开发也一样. 首先,就是及时了解Java整个行业发展信息,包括企业需求的Java岗位要求.行业发展趋势等等,大致做到心中有数,给自己定下目标,确定要进入的企业类别.目标发展城市等. 其次,要做的就是分析自身的实力及能力,根据实际情况制定出一份完整的学

列王的纷争——游戏分析

游戏框架 快速地发展以求能和其余玩家更好的互动. 发展城市是这个游戏的主要部分.因为所有的战斗都只是根据双方队伍的数据直接进行系统判定,并无人为操作,所以只有自己的城市比别人更强大,才能在与其余玩家的对战中获得比较好的体验与满足感. 城市发展分为两个部分,资源采集与城市建设.而资源采集这一块较为简单,玩家也很难出现资源不够用的情况.真正对玩家进行划分的是城市建设这一块.城堡.兵营.行军帐篷等的等级越高,那么出战士兵越厉害,数量越多,也就自然必胜于等级较低的玩家.而城市建设需要花费大量的时间,这也

2013 年最不可思议的 10 个硬件开源项目

这篇文章是总结 2013 年发布的最令人不可思议的开源硬件项目,大部分都是众筹项目,这也说明了在 2013 年,开源业界的创新发展很繁荣,受到很大的关注.与此同时,很多大公司,创业公司和个人开发者都开始对开源创新给予很高的关注度,展望 2014,开源创新将会发展到另一个更高的高度! 五月: 开源实验仪器 Red Pitaya 源代码: 尚未公布 可 以肯定的是,购买实验室器材设备是笔很昂贵的开销,这也是为什么 Red Pitaya 项目组决定要创建一个硬件来改造手机,平板或者是电脑来作为实验的设

2018.3.19 一周第一次课

1.1 学习之初 r.aminglinux.com 学习资源软件包 课程用到的代码及命令 (centos7.aminglinux.com) 选择一个定位(发展方向.发展城市.对未来三年的规划) 学习方法 (预习复习.当日事当日毕.做爱后笔记.利用和资源) 1.2 约定 1.操作系统 centOS 7.4系统 64位 64位 http://mirrors.sohu.com/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-DVD-1708.iso 2.操作i系

冷库设计方案如何设计才能更优化

一.冷库结构和优化目的 1)冷库根据用途的不同分类 1.生产性冷库 生产性冷库是食品企业生产加工工艺组成的一部分.它的主要任务是对企业所加工的食品进行冷却和冻结,并作短期的储存. 2.分配性冷库 这类冷库建在大.中城市,水陆交通枢纽和人口较多的工矿区,它的任务主要是接受储藏已经冷却或冻结的食品,以保证市场的需要.出口计划的完成和长期储备. 3.综合性冷库 这类冷库设有较大的库容量,应有一定的冷却和冷冻能力,它能起到生产性冷库和分配性冷库的双重作用,是普遍应用的一种冷库类型. 2)冷库根据结构的不