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. 【转】DirectorySearcher.Filter属性说明

    DirectorySearcher.Filter属性扩充申明 DirectorySearcher mySearcher = new DirectorySearcher(entryOU, "( ...

  2. windows 批处理文件中引用日期

    参见:http://blog.csdn.net/iw1210/article/details/39313677 %DATE%输出的是: yyyy/mm/dd 星期* (例如:2008/12/18 星期 ...

  3. 美化VC界面(用户登录界面)

    源代码:下载 VC开发程序单调的界面相信大家都是深有感触,提到界面美化编程,人们都会说做界面不要用VC写,太难了.一句俗语:难者不会,会者不难.VC的美化界面编程并没有人们想像的那么难.这篇文章是我写 ...

  4. linux -- Ubuntu查看修改mysql的登录名和密码、安装phpmyadmin

    安装好mysql后,在终端输入 mysql -u root -p 按回车,输入密码后提示access denied......ues password YES/NO的错误 原因是用户名或密码不对! 查 ...

  5. sql字符串的拼接 (字符串和二进制,erlang的mysql驱动)

    1> list_to_binary(["select * from aa limit","1",",","97"] ...

  6. perl chomp 函数的真正作用

    之前一直以为chomp函数只是去掉字符串末尾的\n, 但是今天写程序遇到一个bug,最后的原因就处在chomp上: 读取fasta文件,内容如下: >1 ATGCTAGCTACGTACGTACG ...

  7. 与其他Javascript类库冲突解决方案

    $(document).ready(function() { var $jq = jQuery.noConflict(); $jq('#id').show(); });

  8. makefile--变量的使用(二)

    原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 仔细研究我们的之前Makefile发现,我们还有改进的地方,就是此处: target_bin : ...

  9. [转]ASP.NET MVC 5 - 添加一个模型

    在本节中,您将添加一些类,这些类用于管理数据库中的电影.这些类是ASP.NET MVC 应用程序中的"模型(Model)". 您将使用.NET Framework 数据访问技术En ...

  10. easyui------添加中文文件

    添加中文文件: 官网地址:http://www.jeasyui.net/download/去jquery-easyui官网下载的文件里面找到easyui-lang-zh_CN.js文件,添加入代码里面 ...