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

J. Maze Designer

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 徐州赛区网络预赛](https://nanti.jisuanke.com/acm?kw=ACM-ICPC 2018 徐州赛区网络预赛)

题面:

有一个n*m的空地,可以在每个空地之间建墙,多个询问,问从某一点到另外一点的有且只有一条路并且建墙的总代价最小时的路径长度

思路:

假设开始所有的墙都已经建好了,现在开始拆墙,保证拆的墙一定是最大的,然后算两点之间的距离

解法:拆墙就是找最大生成树,算两点之间的距离用个LCA, 因为有多组询问

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}} inline void getInt(int* p);
const int maxn = 300010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int n, m;
#define N maxn
int getid(int x, int y)
{
return m * (x - 1) + y;
}
struct NODE
{
int next;
int dis;
NODE() { }
NODE(int nn, int dd)
{
next = nn;
dis = dd;
}
};
std::vector<NODE> son[N];
int depth[N], fa[N][21], in[N], a, b;
ll dist[N];
// depth[i] -> i 节点的深度
// fa[i][j] -> i 节点向上移动2^j个节点后的祖先
// fa[i][0] -> i 向上移动1个节点后的祖先,即父节点
// in[i] i节点的入度,用来找树根用的。
// a b 为读边用的。
void addegde(int a, int b, ll dis)
{
cout << a << " " << b << " " << dis << endl;
son[a].push_back(NODE(b, dis));
son[b].push_back(NODE(a, dis));
}
void dfs(int rt, int prev, int dis)
{
depth[rt] = depth[prev] + 1;
dist[rt] = dist[prev] + 1ll;
fa[rt][0] = prev;
for (int i = 1; i < 20; i++)
{
fa[rt][i] = fa[fa[rt][i - 1]][i - 1];
}
for (int i = 0; i < son[rt].size(); i++)
{
if (son[rt][i].next == prev)
continue;
dfs(son[rt][i].next, rt, son[rt][i].dis);
}
}
int LCA(int x, int y)
{
if (depth[x] < depth[y])
swap(x, y);
for (int i = 19; i >= 0; i--)
{
if (depth[x] - (1 << i) >= depth[y])
{
x = fa[x][i];
}
}
if (x == y)
{
return x;
}
for (int i = 19; i >= 0; i--)
{
if (fa[x][i] != fa[y][i])
{
x = fa[x][i];
y = fa[y][i];
}
}
return fa[x][0];
}
ll finddist(int a, int b)
{
ll u = LCA(a, b);
ll L = dist[a] + dist[b] - 2 * dist[u];
return L;
}
struct node
{
int f, t;
ll w;
node() {}
node(int ff, int tt, ll ww)
{
f = ff;
t = tt;
w = ww;
}
bool operator < (const node& b) const
{
return w > b.w;
}
};
std::vector<node> v;
int far[maxn];
void init(int N)
{
repd(i, 1, N)
{
far[i] = i;
}
depth[0] = -1;
}
int findpar(int x)
{
return far[x] == x ? x : far[x] = findpar(far[x]);
}
void mg(int a, int b, ll w)
{
int aa = a;
int bb = b;
a = findpar(a);
b = findpar(b);
if (a != b)
{
far[a] = b;
addegde(aa, bb, w);
}
}
void K()
{
init(n * m);
sort(ALL(v));
for (int i = 0; i < sz(v); ++i)
{
mg(v[i].f, v[i].t, v[i].w);
}
}
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gbtb;
cin >> n >> m;
char op;
ll w;
repd(i, 1, n)
{
repd(j, 1, m)
{
cin >> op >> w;
if (op == 'D')
{
v.push_back(node(getid(i, j), getid(i + 1, j), w));
}
cin >> op >> w;
if (op == 'R')
{
v.push_back(node(getid(i, j), getid(i , j + 1), w));
}
}
}
K();
dfs(1, 0, 0ll);
int q;
cin >> q;
int x1, yy1, x2, y2;
while (q--)
{
cin >> x1 >> yy1 >> x2 >> y2;
cout << finddist(getid(x1, yy1), getid(x2, y2)) << endl;
} return 0;
} inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)的更多相关文章

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

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

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

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

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

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

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

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

  5. ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心)

    ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心) Trace 问答问题反馈 只看题面 35.78% 1000ms 262144K There's a beach in t ...

  6. 计蒜客 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 ...

  7. ACM-ICPC 2018 徐州赛区网络预赛 B(dp || 博弈(未完成)

    传送门 题面: In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl n ...

  8. 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 ...

  9. ACM-ICPC 2018 徐州赛区网络预赛 F. Features Track

    262144K   Morgana is learning computer vision, and he likes cats, too. One day he wants to find the ...

随机推荐

  1. java 中 this 和 super 说明及在构造器中super()和this()相互调用执行顺序

    this this 表示当前对象 使用上细分的话,this有 this. 和this()的使用情况 ,下面我们开始细撸 this . 使用场景一: 在成员方法中,this.变量名 指带当前对象的变量, ...

  2. codevs 3031:最富有的人

    题目描述 Description 在你的面前有n堆金子,你只能取走其中的两堆,且总价值为这两堆金子的xor值,你想成为最富有的人,你就要有所选择. 输入描述 Input Description 第一行 ...

  3. hdoj4276(树形dp+分组背包)

    题目链接:https://vjudge.net/problem/HDU-4276 题意:给出一棵树,起点为1,时间为V,终点为n,每个点有一个价值a[u],每条边有一个时间花费w,求在时间V内到达终点 ...

  4. poj3304(叉积判断直线和线段相交)

    题目链接:https://vjudge.net/problem/POJ-3304 题意:求是否能找到一条直线,使得n条线段在该直线的投影有公共点. 思路: 如果存在这样的直线,那么在公共投影点作直线的 ...

  5. [转帖]关于 /dev/urandom 的流言终结 | Linux 中国

    关于 /dev/urandom 的流言终结 | Linux 中国 2019年05月05日 14:03:52 技术无边 阅读数 202   版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权 ...

  6. FastJson 介绍

    Json详解 Json是一种轻量级的数据交换格式,采用一种“键:值”对的文本格式来存储和表示数据,在系统交换数据过程中常常被使用,是一种理想的数据交换语言.在使用 Java 做 Web 开发时,不可避 ...

  7. 1.5JdbcTmeplates、Jpa、Mybatis、beatlsql、Druid的使用

    Spring boot 连接数据库整合 -- create table `account`DROP TABLE `account` IF EXISTSCREATE TABLE `account` ( ...

  8. C# U盘扫描

    无意中看到的一个例程,保留一份.   以供后用.     using System; using System.Collections.Generic; using System.ComponentM ...

  9. 作为小白该如何抉择python编辑器?

    刚开始接触编程,有一个好的编辑器上手,那学习起来肯定是事半功倍的!本篇就给大家介绍适合零基础小白学习Python的四种编辑器,希望大家受用! 1.Sublime Text: 这是一个轻量级的代码编辑器 ...

  10. docker 入门6 - 部署 【翻译】

    开始,第 6 部分:部署应用 先决条件 安装 Docker. 获取第 3 部分先决条件中所述的 Docker Compose. 获取 Docker Machine,如第 4 部分先决条件中所述. 阅读 ...