After the long vacation, the maze designer master has to do his job. A tour company gives him a map which is a rectangle. The map consists of N \times MN×M little squares. That is to say, the height of the rectangle is NN and the width of the rectangle is MM. The master knows exactly how the maze is going to use. The tour company will put a couple in two different squares in the maze and make them seek each other. Of course,the master will not make them find each other easily. The only thing the master does is building some wall between some little squares. He knows in that way, wherever the couple is put, there is only one path between them. It is not a difficult thing for him, but he is a considerate man. He also knows that the cost of building every wall between two adjacent squares is different(Nobody knows the reason). As a result, he designs the maze to make the tour company spend the least money to build it.

Now, here's your part. The tour company knows you're the apprentice of the master, so they give you a task. you're given QQ qustions which contain the information of where the couple will be put. You need to figure out the length of the shortest path between them.

However,the master doesn't tell you how he designs the maze, but he believes that you, the best student of himself, know the way. So he goes on vacation again.

Input

The first line of the input contains two integers NN and MM (1 \le N,M \le 5001≤N,M≤500), giving the number of rows and columns of the maze.

The next N \times MN×M lines of the input give the information of every little square in the maze, and their coordinates are in order of (1,1)(1,1) , (1,2)(1,2) \cdots⋯ (1,M)(1,M) , (2,1)(2,1) , (2,2)(2,2) , \cdots⋯ , (2,M)(2,M) , \cdots⋯ ,(N,M)(N,M).

Each line contains two characters DD and RR and two integers aa , bb (0 \le a,b \le 20000000000≤a,b≤2000000000 ), aa is the cost of building the wall between it and its lower adjacent square, and bb is the cost of building the wall between it and its right adjacent square. If the side is boundary, the lacking path will be replaced with X 00.

The next line contains an integer QQ (1 \le Q \le 1000001≤Q≤100000 ), which represents the number of questions.

The next QQ lines gives four integers, x_1x1​, y_1y1​, x_2x2​, y_2y2​ ( 1 \le x_11≤x1​ , x_2 \le Nx2​≤N , 1 \le y_11≤y1​ , y_2 \le My2​≤M ), which represent two squares and their coordinate are (x_1x1​ , y_1y1​) and (x_2x2​ , y_2y2​).

(xx,yy) means row xx and column yy.

It is guaranteed that there is only one kind of maze.

Output

For each question, output one line with one integer which represents the length of the shortest path between two given squares.

样例输入复制

3 3
D 1 R 9
D 7 R 8
D 4 X 0
D 2 R 6
D 12 R 5
D 3 X 0
X 0 R 10
X 0 R 11
X 0 X 0
3
1 1 3 3
1 2 3 2
2 2 3 1

样例输出复制

4
2
2

题目来源

ACM-ICPC 2018 徐州赛区网络预赛

题意:

有一个n*m的方格

每个小格子之间有一道墙 给定建这道墙的价格

要求建一些墙 使得方格内的任意两个小方格之间都只有唯一的一条路径 并且要使这个建墙方式花费最小

现在给定q组坐标

问这对坐标的路径长度

思路:

应该要想到树的性质之一是 结点之间只有唯一的一条路径

这道题相当于把小格子转换为节点 墙转换为边 花费转换为权值

构造一棵最大生成树 不在树中的这些边表示需要建墙

对于每一组查询 查找最近公共祖先 深度之差的和即为答案

一直只过了8组样例 WA到现在还不知道什么问题

有时间可能需要重新写一下 显示说是段错误 但是我数组什么的好像也已经开的足够大了啊

可能哪里访问有点问题


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<cmath>
#include<set>
//#include<bits/stdc++.h>
#define inf 0x7f7f7f7f7f7f7f7f
using namespace std;
typedef long long LL; const int maxn = 600;
LL n, m, cntedge;
LL depth[maxn * maxn], upfa[maxn * maxn][30], par[maxn * maxn]; struct edge {
LL u, v;
LL cost;
}e[maxn * maxn * 2];
vector<edge> etree[maxn * maxn]; bool cmp(edge a, edge b)
{
return a.cost > b.cost;
} void dfs(LL u, LL pre, LL d)
{
upfa[u][0] = pre;
depth[u] = d;
for (LL i = 0; i < etree[u].size(); i++) {
LL v = etree[u][i].v;
if (v != pre) {
dfs(v, u, d + 1);
}
}
} void initlca()
{
dfs(0, -1, 0);
for (LL j = 0; (1 << (j + 1)) < n * m; j++) {
for (LL i = 0; i < n * m; i++) {
if (upfa[i][j] < 0) {
upfa[i][j + 1] = -1;
}
else {
upfa[i][j + 1] = upfa[upfa[i][j]][j];
}
}
}
} void init()
{
for (LL i = 0; i < n * m; i++) {
par[i] = i;
etree[i].clear();
} memset(depth, 0, sizeof(depth));
memset(upfa, -1, sizeof(upfa));
cntedge = 0;
} LL lca(LL u, LL v)
{
if (depth[u] > depth[v]) {
swap(u, v);
}
LL temp = depth[v] - depth[u];
for (LL i = 0; (1 << i) <= temp; i++) {
if ((1 << i) & temp) {
v = upfa[v][i];
}
}
if (v == u) return u;
for (LL i = (LL)log2(n * m * 1.0); i >= 0; i--) {
if (upfa[u][i] != upfa[v][i]) {
u = upfa[u][i];
v = upfa[v][i];
}
}
return upfa[u][0];
} int find(int x)
{
LL rt = x;
while (rt != par[rt]) {
rt = par[rt];
}
while (x != rt) {
LL t = par[x];
par[x] = rt;
x = t;
}
return rt;
} void unite(LL x, LL y)
{
x = find(x);
y = find(y);
if (x != y) {
par[x] = y;
}
} void kruskal()
{
sort(e, e + cntedge, cmp);
LL nedge = 0;
for (LL i = 0; i < cntedge && nedge < m * n - 1; i++) {
if (find(e[i].u) != find(e[i].v)) {
etree[e[i].u].push_back(e[i]);
edge tmp;
tmp.u = e[i].v;
tmp.v = e[i].u;
tmp.cost = e[i].cost;
etree[tmp.u].push_back(tmp);
unite(e[i].u, e[i].v);
nedge++;
}
}
} int main()
{
scanf("%lld%lld", &n, &m);
init();
for (LL i = 0; i < n * m; i++) {
char ch1[5], ch2[5];
LL a, b;
scanf("%s %lld %s %lld", ch1, &a, ch2, &b);
if (ch1[0] != 'X') {
e[cntedge].u = i;
e[cntedge].v = i + m;
e[cntedge].cost = a;
cntedge++;
e[cntedge].u = i + m;
e[cntedge].v = i;
e[cntedge].cost = a;
cntedge++;
}
if (ch2[0] != 'X') {
e[cntedge].u = i;
e[cntedge].v = i + 1;
e[cntedge].cost = b;
cntedge++;
e[cntedge].u = i + 1;
e[cntedge].v = i;
e[cntedge].cost = b;
cntedge++;
}
} LL q;
kruskal();
initlca();
scanf("%lld", &q);
while (q--) {
LL x1, x2, y1, y2;
scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2);
x1--; y1--; x2--; y2--;
LL father = lca(x1 * m + y1, x2 * m + y2);
LL ans = depth[x1 * m + y1] - 2 * depth[father] + depth[x2 * m + y2];
printf("%lld\n", ans);
} return 0;
}

找到的AC 代码:

#include <bits/stdc++.h>
const int maxn = 507;
struct { int next, v; } edge[maxn * maxn << 1];
int dep[maxn * maxn], n, m, up[maxn * maxn][27], tot, q;
int index(int x, int y) { return (x - 1) * m + y; }
namespace graph {
int head[maxn * maxn], cnt;
void addedge(int u, int v) {
edge[++cnt] = {head[u], v};
head[u] = cnt;
}
}
void bfs() {
memset(up, 0xff, sizeof(up));
std::queue<int> que;
que.push(1);
dep[1] = 1;
while (!que.empty()) {
int u = que.front();
que.pop();
for (int i = graph::head[u]; i; i = edge[i].next) {
int v = edge[i].v;
if (dep[v] == 0) {
dep[v] = dep[u] + 1;
up[v][0] = u;
que.push(v);
}
}
}
for (int j = 1; j <= 22; j++) {
for (int i = 1; i <= n * m; i++) {
if (~up[i][j - 1]) up[i][j] = up[up[i][j - 1]][j - 1];
}
}
}
int query(int u, int v) {
if (dep[u] < dep[v]) std::swap(u, v);
int tmp = dep[u] - dep[v];
for (int j = 0; tmp; j++) if (tmp & (1 << j)) tmp ^= (1 << j), u = up[u][j];
if (u == v) return u;
for (int j = 22; ~j; j--) if (up[u][j] != up[v][j]) u = up[u][j], v = up[v][j];
return up[u][0];
}
struct Disjoint {
int pre[maxn * maxn];
Disjoint() { for (int i = 0; i < maxn * maxn; i++) pre[i] = i; }
int find(int x) { return x == pre[x] ? x : pre[x] = find(pre[x]); }
void merge(int x, int y) { if (x != y) pre[x] = y; }
} disjoint;
struct Edge { int u, v, cost; } edges[maxn * maxn << 1];
int main() {
scanf("%d%d", &n, &m);
char ch;
for (int i = 1, cost; i <= n; i++) {
for (int j = 1; j <= m; j++) {
for (int k = 0; k < 2; k++) {
scanf(" %c%d", &ch, &cost);
if (ch != 'X') {
if (ch == 'R') edges[tot++] = {index(i, j), index(i, j + 1), cost};
else edges[tot++] = {index(i, j), index(i + 1, j), cost};
}
}
}
}
std::sort(edges, edges + tot, [](Edge x, Edge y) { return x.cost > y.cost; });
for (int i = 0; i < tot; i++) {
int u = disjoint.find(edges[i].u), v = disjoint.find(edges[i].v);
if (u != v) {
graph::addedge(edges[i].u, edges[i].v);
graph::addedge(edges[i].v, edges[i].u);
disjoint.merge(u, v);
}
}
bfs();
scanf("%d", &q);
for (int i = 0, x, y, a, b; i < q; i++) {
scanf("%d%d%d%d", &x, &y, &a, &b);
int u = index(x, y), v = index(a, b), lca = query(u, v);
printf("%d\n", dep[u] + dep[v] - 2 * dep[lca]);
}
return 0;
}

徐州网络赛J-Maze Designer【最小生成树】【LCA】的更多相关文章

  1. ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)

    ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer J. Maze Designer After the long vacation, the maze designer ...

  2. ACM-ICPC 2018 徐州赛区网络预赛 J Maze Designer(最大生成树+LCA)

    https://nanti.jisuanke.com/t/31462 题意 一个N*M的矩形,每个格点到其邻近点的边有其权值,需要构建出一个迷宫,使得构建迷宫的边权之和最小,之后Q次查询,每次给出两点 ...

  3. ACM-ICPC 2018 徐州赛区网络预赛 J Maze Designer(最大生成树,倍增lca)

    https://nanti.jisuanke.com/t/31462 要求在一个矩形中任意选两个点都有唯一的通路,所以不会建多余的墙. 要求满足上述情况下,建墙的费用最小.理解题意后容易想到首先假设全 ...

  4. ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer 最大生成树 lca

    大概就是要每两个点 只能有一条路径,并且约束,最短的边用来砌墙,那么反之的意思就是最大的边用来穿过 故最大生成树 生成以后 再用lca计算树上两点间的距离 (当然防止生成树是一条链,可以用树的重心作为 ...

  5. ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer

    传送门:https://nanti.jisuanke.com/t/31462 本题是一个树上的问题:结点间路径问题. 给定一个有N×M个结点的网格,并给出结点间建立墙(即拆除边)的代价.花费最小的代价 ...

  6. [2019徐州网络赛J题]Random Access Iterator

    题目链接 大致题意:从根节点出发,在节点x有son[x]次等概率进入儿子节点,求到达最深深度的概率.son[x]为x节点的儿子节点个数. 又又又又没做出来,心态崩了. 下来看了官方题解后发觉自己大体思 ...

  7. 2018 ICPC 徐州网络赛

    2018 ICPC 徐州网络赛 A. Hard to prepare 题目描述:\(n\)个数围成一个环,每个数是\(0\)~\(2^k-1\),相邻两个数的同或值不为零,问方案数. solution ...

  8. 计蒜客 41391.query-二维偏序+树状数组(预处理出来满足情况的gcd) (The Preliminary Contest for ICPC Asia Xuzhou 2019 I.) 2019年徐州网络赛)

    query Given a permutation pp of length nn, you are asked to answer mm queries, each query can be rep ...

  9. ICPC 2019 徐州网络赛

    ICPC 2019 徐州网络赛 比赛时间:2019.9.7 比赛链接:The Preliminary Contest for ICPC Asia Xuzhou 2019 赛后的经验总结 // 比赛完才 ...

  10. [徐州网络赛]Longest subsequence

    [徐州网络赛]Longest subsequence 可以分成两个部分,前面相同,然后下一个字符比对应位置上的大. 枚举这个位置 用序列自动机进行s字符串的下标转移 注意最后一个字符 #include ...

随机推荐

  1. implicit declaration of function 'copy_from_user'

    内核中使用copy_from_user()和copy_to_user()函数,编译出现错误: implicit declaration of function 'copy_from_user' 需要添 ...

  2. e658. 组合图形

    Area shape = new Area(shape1); shape.add(new Area(shape2)); shape.subtract(new Area(shape3)); shape. ...

  3. erlang和java的socket通讯----最简单,初次实现。

    直接上源码,留做纪念. 有点简单,大家不要笑,初次实现. 功能描述:java发送数据给erlang,erlang将收到的数据重复两次再发送给java. erlang源码:模块tcp_listen -m ...

  4. Qt 定时器Timer使用

    From: http://dragoon666.blog.163.com/blog/static/107009194201092602326598/ 1.新建Gui工程,在主界面上添加一个标签labe ...

  5. php error_log错误信息写入文件

  6. MySQL(五)之DDL(数据定义语言)与六大约束

    前言 前面在数据库的讲解中,其实很多东西都非常的细节,在以前的学习过程中我都是没有注意到的.可能在以后的工作中会碰到所以都是做了记录的. 接下来,我将分享的是MySQL的DDL用来对数据库及表进行操作 ...

  7. GC之二--GC是如何回收时的判断依据、shallow(浅) size、retained(保留) size、Deep(深)size

    回到问题“为何会内存溢出?”. 要回答这个问题又要引出另外一个话题,既什么样的对象GC才会回收? 一.对象存活方式判断方法 在上一篇文章<GC之一--GC 的算法分析.垃圾收集器.内存分配策略介 ...

  8. Shell 文本处理工具

    转载自:http://www.cnblogs.com/wish123/p/5540210.html Linux下使用Shell处理文本时最常用的工具: find.grep.xargs.sort.uni ...

  9. ubuntu普通用户无法使用usdo命令

    1.切换到root用户下,怎么切换就不用说了吧,不会的自己百度去. 2.添加sudo文件的写权限,命令是: chmod u+w /etc/sudoers 3.编辑sudoers文件 vi /etc/s ...

  10. elastic-job(lite)使用的一些注意事项

    前段时间项目开发中用到了当当开源的elastic-job,使用过程遇到一些问题,虽然不见得会影响写代码,但作为一个致力于搬好每一块砖的码农,当碰到问题时,我们不应该逃避,应该本着有困难也要上,没有困难 ...