徐州网络赛J-Maze Designer【最小生成树】【LCA】
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
题目来源
题意:
有一个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】的更多相关文章
- 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 徐州赛区网络预赛 J. Maze Designer
传送门:https://nanti.jisuanke.com/t/31462 本题是一个树上的问题:结点间路径问题. 给定一个有N×M个结点的网格,并给出结点间建立墙(即拆除边)的代价.花费最小的代价 ...
- [2019徐州网络赛J题]Random Access Iterator
题目链接 大致题意:从根节点出发,在节点x有son[x]次等概率进入儿子节点,求到达最深深度的概率.son[x]为x节点的儿子节点个数. 又又又又没做出来,心态崩了. 下来看了官方题解后发觉自己大体思 ...
- 2018 ICPC 徐州网络赛
2018 ICPC 徐州网络赛 A. Hard to prepare 题目描述:\(n\)个数围成一个环,每个数是\(0\)~\(2^k-1\),相邻两个数的同或值不为零,问方案数. solution ...
- 计蒜客 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 ...
- ICPC 2019 徐州网络赛
ICPC 2019 徐州网络赛 比赛时间:2019.9.7 比赛链接:The Preliminary Contest for ICPC Asia Xuzhou 2019 赛后的经验总结 // 比赛完才 ...
- [徐州网络赛]Longest subsequence
[徐州网络赛]Longest subsequence 可以分成两个部分,前面相同,然后下一个字符比对应位置上的大. 枚举这个位置 用序列自动机进行s字符串的下标转移 注意最后一个字符 #include ...
随机推荐
- e674. 创建并绘制加速图像
Images in accelerated memory are much faster to draw on the screen. This example demonstrates how to ...
- 不可在 for 循环体内修改循环变量,防止 for 循环失去控制
不可在 for 循环体内修改循环变量,防止 for 循环失去控制. #include <iostream> /* run this program using the console pa ...
- Java处理图片时编译不通过
Java中处理图片时,MyEclipse需要导入以下包: import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.j ...
- BinarySearchTree二叉搜索树的实现
/* 二叉搜索树(Binary Search Tree),(又:二叉查找树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; ...
- MyEclipse安装EGit插件方法
摘要: 先了解自己的MyEclipse是基于哪个版本的Eclipse优化的,然后到EGit网站找对应的EGit版本,下载压缩包,解压安装. 在网上看到有人说并不是任意版本的EGit插件都能适配你的My ...
- [转]JVM运行时内存结构
[转]http://www.cnblogs.com/dolphin0520/p/3783345.html 目录[-] 1.为什么会有年轻代 2.年轻代中的GC 3.一个对象的这一辈子 4.有关年轻代的 ...
- [转]ASP.NET MVC 5 - 将数据从控制器传递给视图
在我们讨论数据库和数据模型之前,让我们先讨论一下如何将数据从控制器传递给视图.控制器类将响应请求来的URL.控制器类是给您写代码来处理传入请求的地方,并从数据库中检索数据,并最终决定什么类型的返回结果 ...
- 工作流JBPM_day01:7-使用流程变量
工作流JBPM_day01:7-使用流程变量 工作流就像流水线 对应数据库中的一张表 ProcessVariableTest.Java import java.util.List; import or ...
- POJ 1018 Communication System(树形DP)
Description We have received an order from Pizoor Communications Inc. for a special communication sy ...
- laravel 社会化(联合)登录扩展包(QQ、微信、微博等)
laravel的官方包只支付国外网站的联合登录:http://laravelacademy.org/post/6288.html 国内用户的话,可以用这个:https://github.com/ove ...