ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer
传送门:https://nanti.jisuanke.com/t/31462
本题是一个树上的问题:结点间路径问题。
给定一个有N×M个结点的网格,并给出结点间建立墙(即拆除边)的代价。花费最小的代价,使得每一对结点之间的路径唯一。给出Q次询问:每次询问一对结点的路径长度。
每一对结点之间存在路径,则图是连通的;路径唯一,则图是无环的。于是拆除边后的图是原图的一棵生成树。为使得拆除的代价尽可能小,这棵生成树应是最大生成树。通过Kruskal算法,可以求解最大生成树。
之后,即是询问树结点对的路径长度。这个问题可以通过LCA算法求解。
设结点u、v的LCA为结点k,即k=LCA(u,v),则dis(u,v)=dep[u]+dep[v]-2*dep[k]。此处通过倍增实现LCA。
参考程序如下:
#include <bits/stdc++.h>
using namespace std; #define MAX_N 300005 priority_queue<pair<int, pair<int, int> > > edge;
vector<int> adj[MAX_N]; //Union Find.
int fa[MAX_N]; void init_dset(int n)
{
for (int i = ; i < n; i++) fa[i] = i;
} int find(int u)
{
if (fa[u] == u) return u;
return fa[u] = find(fa[u]);
} void unite(int u, int v)
{
int fu = find(u), fv = find(v);
if (fu == fv) return;
fa[fu] = fv;
} bool same(int u, int v)
{
return find(u) == find(v);
} //LCA.
int pre[][MAX_N]; //Ancestor Nodes.
int dep[MAX_N]; //Depth of Nodes. void dfs(int u, int p)
{
pre[][u] = p;
for (int v : adj[u]) {
if (v != p) {
dep[v] = dep[u] + ;
dfs(v, u);
}
}
} void init_lca(int n)
{
dfs(, -);
for (int k = ; k < ; k++) {
for (int v = ; v < n; v++) {
if (pre[k][v]) pre[k + ][v] = pre[k][pre[k][v]];
}
}
} int lca(int u, int v)
{
if (dep[u] > dep[v]) swap(u, v);
for (int k = ; k < ; k++) {
if ((dep[v] - dep[u]) & ( << k)) v = pre[k][v];
}
if (u == v) return u;
for (int k = ; k >= ; k--) {
if (pre[k][u] != pre[k][v]) {
u = pre[k][u];
v = pre[k][v];
}
}
return pre[][u];
} int main(void)
{
ios::sync_with_stdio(false);
int n, m;
cin >> n >> m;
for (int i = ; i < n; i++) {
for (int j = ; j < m; j++) {
string s, t;
int a, b;
cin >> s >> a >> t >> b;
if (s[] == 'D') {
int u = i * m + j;
int v = (i + ) * m + j;
edge.push(make_pair(a, make_pair(u, v)));
}
if (t[] == 'R') {
int u = i * m + j;
int v = i * m + j + ;
edge.push(make_pair(b, make_pair(u, v)));
}
}
}
init_dset(n * m);
while (!edge.empty()) {
auto e = edge.top();
edge.pop();
int u = e.second.first;
int v = e.second.second;
if (!same(u, v)) {
unite(u, v);
adj[u].push_back(v);
adj[v].push_back(u);
}
}
init_lca(n * m);
int q;
cin >> q;
while (q--) {
int a, b, c, d;
cin >> a >> b >> c >> d;
a--; b--; c--; d--;
int u = a * m + b;
int v = c * m + d;
int k = lca(u, v);
cout << dep[u] + dep[v] - * dep[k] << endl;
}
}
ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer的更多相关文章
- ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)
ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer J. Maze Designer After the long vacation, the maze designer ...
- ACM-ICPC 2018 徐州赛区网络预赛 J Maze Designer(最大生成树+LCA)
https://nanti.jisuanke.com/t/31462 题意 一个N*M的矩形,每个格点到其邻近点的边有其权值,需要构建出一个迷宫,使得构建迷宫的边权之和最小,之后Q次查询,每次给出两点 ...
- ACM-ICPC 2018 徐州赛区网络预赛 J Maze Designer(最大生成树,倍增lca)
https://nanti.jisuanke.com/t/31462 要求在一个矩形中任意选两个点都有唯一的通路,所以不会建多余的墙. 要求满足上述情况下,建墙的费用最小.理解题意后容易想到首先假设全 ...
- ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer 最大生成树 lca
大概就是要每两个点 只能有一条路径,并且约束,最短的边用来砌墙,那么反之的意思就是最大的边用来穿过 故最大生成树 生成以后 再用lca计算树上两点间的距离 (当然防止生成树是一条链,可以用树的重心作为 ...
- ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心)
ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心) Trace 问答问题反馈 只看题面 35.78% 1000ms 262144K There's a beach in t ...
- 计蒜客 1460.Ryuji doesn't want to study-树状数组 or 线段树 (ACM-ICPC 2018 徐州赛区网络预赛 H)
H.Ryuji doesn't want to study 27.34% 1000ms 262144K Ryuji is not a good student, and he doesn't wa ...
- ACM-ICPC 2018 徐州赛区网络预赛 B(dp || 博弈(未完成)
传送门 题面: In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl n ...
- ACM-ICPC 2018 徐州赛区网络预赛 B. BE, GE or NE
In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl named &qu ...
- ACM-ICPC 2018 徐州赛区网络预赛 F. Features Track
262144K Morgana is learning computer vision, and he likes cats, too. One day he wants to find the ...
随机推荐
- mybatis中各种数据的映射类型
Mybatis对应的java和数据库的数据类型,最后有图片 Mybatis java ...
- Bug分支(转载)
转自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137602359178 ...
- Python机器学习算法 — 逻辑回归(Logistic Regression)
逻辑回归--简介 逻辑回归(Logistic Regression)就是这样的一个过程:面对一个回归或者分类问题,建立代价函数,然后通过优化方法迭代求解出最优的模型参数,然后测试验证我们这个求解的模型 ...
- bzoj 1725: [Usaco2006 Nov]Corn Fields牧场的安排【状压dp】
压一维状态,转移时把符合条件的上一行加上 #include<iostream> #include<cstdio> using namespace std; const int ...
- json和Jsonp 使用总结(1)
1.Json的使用 $.getJSON("subPreview", { jsonDatas: JSON.stringify(jsonData) }, function(data) ...
- android序列化(2)Parcelable与Parcel
1.简介 Parcel : 包裹 Android采用这个它封装消息数据.这个是通过IBinder通信的消息的载体.需要明确的是Parcel用来存放数据的是内存(RAM),而不是永久性介质(Nand等 ...
- Javascript DOM 编程艺术(第二版)读书笔记——DOM基础
1.DOM是什么 D=document(文档) O=object(对象) M=Model(模型) DOM又称节点树 一些术语: parent(父) child(子) sibling(兄弟) ...
- Spark学习之基础相关组件(1)
Spark学习之基础相关组件(1) 1. Spark是一个用来实现快速而通用的集群计算的平台. 2. Spark的一个主要特点是能够在内存中进行计算,因而更快. 3. RDD(resilient di ...
- Asp.net MVC中文件上传的参数转对象的方法
参照博友的.NET WebApi上传文件接口(带其他参数)实现文件上传并带参数,当需要多个参数时,不想每次都通过HttpContext.Request.Params去取值,就针对HttpRequest ...
- python自动化--语言基础四模块、文件读写、异常
模块1.什么是模块?可以理解为一个py文件其实就是一个模块.比如xiami.py就是一个模块,想引入使用就在代码里写import xiami即可2.模块首先从当前目录查询,如果没有再按path顺序逐一 ...