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. C++ 中的空格

    C++ 中的空格只包含空格的行,被称为空白行,可能带有注释,C++ 编译器会完全忽略它. 在 C++ 中,空格用于描述空白符.制表符.换行符和注释.空格分隔语句的各个部分,让编译器能识别语句中的某个元 ...

  2. API Design Principles -- QT Project

    [the original link] One of Qt’s most reputed merits is its consistent, easy-to-learn, powerfulAPI. T ...

  3. KO 数据库分类系统介绍

    KEGG Orthology数据库不仅对基因的功能进行了扩充和整理,还对功能进行了细致的分类: 针对基因的功能,共有3级分类,第一级有6个大类: 打开下面这个链接 http://www.genome. ...

  4. Tomcat 配置 项目 到tomcat目录外面 和 域名绑定访问(api接口、前端网站、后台管理网站)

    先停止tomcat服务 1.进入apache-tomcat-7.0.68/conf/Catalina/localhost(如果之前还都没有启动过tomcat,是不会有此目录的,先启动一次再关闭,会自动 ...

  5. centos7 修改主机名的方法(在centos7有效)

    参考链接:http://www.centoscn.com/CentOS/config/2014/1031/4039.html 在CentOS或RHEL中,有三种定义的主机名:a.静态的(static) ...

  6. 如何用MathType编辑化学等式

    MathType在数学中应用非常广泛,被大量用于编辑数学公式,MathType不仅可以用来编辑数学公式,还可以编辑化学反应式,那么MathType编辑化学等式怎么操作的呢? 具体操作如下: 1.打开M ...

  7. 【转自IT虾米网:www.itxm.net】外部应用和drools-wb6.1集成解决方案

    一.手把手教你集成外部应用和drools workbench6.1 1.         首先按照官方文档安装workbench ,我用的是最完整版的jbpm6-console的平台系统,里面既包含j ...

  8. 使用Dreamweaver开发php

    1.新建站点,开发的目录 2.服务器,服务器的目录   (并修改为“测试”) 3.必须结合WANP5

  9. 给嵌入式ARM+Linux的初学者

    http://blog.csdn.net/lucykingljj/article/details/40619671

  10. php 网络爬虫,爬一下花瓣的图片

    今天无聊看在知乎上看到有人写网络爬虫爬图片( ̄▽  ̄) 传送门: 福利 - 不过百行代码的爬虫爬取美女图:https://zhuanlan.zhihu.com/p/24730075 福利 - 不过十行 ...