徐州网络赛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 ...
随机推荐
- ubuntu/centos网络配置
UBUNTU网络配置 配置临时的Ip ifconfig eth0 其中24指的网络掩码24位. vim /etc/network/interfaces 添加下面内容 auto eth0 #开机自动连接 ...
- Java调用FTP实例
package com.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStre ...
- linux 访问远程务器代码
比如用SSH 访问远程 登陆名为hadoop 的IP为192.168.1.35的主机,则用ssh hadoop@192.168.1.35,然后依据提示输入密码即可.
- Java 实现选择排序
选择排序: 原理:依次从数组最左边取一个元素,与之后的位置上的元素比較,假设大于/小于(取决于须要升序排还是降序排).则保存较大/较小元素的索引 当一轮比較后,将保存的较大/较小元素的索引与 这轮開始 ...
- 从css样式表中抽取元素尺寸
jS从样式表取值的函数.IE中以currentStyle,firefox中defaultView来获取 DOM.style仅仅能读到写在html中的样式值 获取样式值的函数 function retu ...
- swif开发之--协议的使用
以前在oc构建的项目中,如果这个页面需要构建一些指定的页面,一般我会重新创建个集成与UIView的类,然后同时创建XXX.xib文件,然后直接在上面拖拽控件,非常快速,当然也可以手动布局!个人更喜欢可 ...
- ArcGIS ArcPy Python处理数据
1.使用搜索游标查看行中的字段值.import arcpy # Set the workspace arcpy.env.workspace = "c:/base/data.gdb" ...
- YARN 中的应用程序提交
YARN 中的应用程序提交 本节讨论在应用程序提交到 YARN 集群时,ResourceManager.ApplicationMaster.NodeManagers 和容器如何相互交互.下图显示了一个 ...
- linux连接sybase数据库-isql
转自:http://blog.knowsky.com/196438.htm 想要linux连接sybase数据库用命令isql: isql [-U login id] [-P password] [- ...
- 今天是学习C#面向过程的最后的一天
今天学习完啦面向过程,可能写法也就是那些,固定不变的,但是程序的写法就是由自己决定······ 今天学习了调用已经存在的方法,就是在.net Framework 中存在的方法,具体今天提到的有这些, ...