ACM-ICPC 2018 徐州赛区网络预赛 J Maze Designer(最大生成树+LCA)
https://nanti.jisuanke.com/t/31462
题意
一个N*M的矩形,每个格点到其邻近点的边有其权值,需要构建出一个迷宫,使得构建迷宫的边权之和最小,之后Q次查询,每次给出两点坐标,给出两点之间的最短路径
分析
可以把每个格点视作视作图的点,隔开两点的边视作图的边,则构建迷宫可以视作求其生成树,剩余的边就是组成迷宫的墙.因为要花费最小,所以使删去的墙权置最大即可,呢么就是求最大生成树即可.
然后每次查询相当于查这个最大生成树上任意两点的最短距离,到这一步就是个LCA了。
这题码量不少,还好队友给力。
#include <iostream>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <map>
#include <algorithm>
#include <queue>
#include <set>
#include <cmath>
#include <sstream>
#include <stack>
#include <fstream>
#include <ctime>
#pragma warning(disable:4996);
#define mem(sx,sy) memset(sx,sy,sizeof(sx))
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-;
const double PI = acos(-1.0);
const ll llINF = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
using namespace std;
//#define pa pair<int, int>
//const int mod = 1e9 + 7;
const int maxn = ;
const int maxq = ;
struct node {
int u, v, w, next, lca;
}; struct LCA {
node edges[maxn], ask[maxq];
int ghead[maxn], gcnt, ahead[maxn], acnt;
int anc[maxn];
int vis[maxn];
ll dist[maxn];
int fa[maxn]; void addedge(int u, int v, int w) {
edges[gcnt].v = v;
edges[gcnt].w = w;
edges[gcnt].next = ghead[u];
ghead[u] = gcnt++;
} void addask(int u, int v) {
ask[acnt].u = u;
ask[acnt].v = v;
ask[acnt].next = ahead[u];
ahead[u] = acnt++;
} void init() {
mem(vis, );
mem(ghead, -);
mem(ahead, -);
gcnt = ;
acnt = ;
} int Find(int x) {
return fa[x] == x ? x : (fa[x] = Find(fa[x]));
} void getLCA(int u, int d) {
dist[u] = d;
fa[u] = u;
vis[u] = ;
for (int i = ghead[u]; i != -; i = edges[i].next) {
int v = edges[i].v;
if (!vis[v]) {
getLCA(v, d + edges[i].w);
fa[v] = u;
anc[fa[v]] = u;
}
}
for (int i = ahead[u]; i != -; i = ask[i].next) {
int v = ask[i].v;
if (vis[v])
ask[i].lca = ask[i ^ ].lca = Find(ask[i].v);
} } }L; struct edge {
int u, v;
ll w;
bool operator<(const edge &e)const { return w>e.w; }
edge(int _u = , int _v = , ll _w = )
:u(_u), v(_v), w(_w) {}
}; struct Kruskal {
int n, m;
edge edges[maxn];
int fa[maxn];
int Find(int x) {
return fa[x] == - ? x : fa[x] = Find(fa[x]);
}
void init(int _n) {
this->n = _n;
m = ;
mem(fa, -);
} void AddEdge(int u, int v, ll dist) {
edges[m++] = edge(u, v, dist);
} ll kruskal() {
ll sum = ;
int cntnum = ;
sort(edges, edges + m);
for (int i = ; i < m; i++) {
int u = edges[i].u, v = edges[i].v;
if (Find(u) != Find(v)) {
L.addedge(u, v, );
L.addedge(v, u, );
//cout << u << " " << v << endl;
sum += edges[i].w;
fa[Find(u)] = Find(v);
if (++cntnum >= n - ) return sum;
}
}
return -;
}
}G; int main() {
int n, m;
while (~scanf("%d%d", &n, &m)) {
G.init(n*m);
L.init();
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
int w1, w2; char c1, c2;
scanf(" %c%d %c%d", &c1, &w1, &c2, &w2);
if (c1 == 'D') {
G.AddEdge((i - )*m + j, i*m + j, w1);
}
if (c2 == 'R') {
G.AddEdge((i - )*m + j, (i - )*m + j + , w2);
}
}
}
G.kruskal();
int q;
scanf("%d", &q);
for (int i = , x1, x2, y1, y2; i <= q; i++) {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
int u = (x1 - )*m + y1;
int v = (x2 - )*m + y2;
L.addask(u, v);
L.addask(v, u);
}
L.getLCA(, );
for (int i = ; i < L.acnt; i += ) {
printf("%lld\n", L.dist[L.ask[i].u] + L.dist[L.ask[i].v] - * L.dist[L.ask[i].lca]);
}
}
}
ACM-ICPC 2018 徐州赛区网络预赛 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
大概就是要每两个点 只能有一条路径,并且约束,最短的边用来砌墙,那么反之的意思就是最大的边用来穿过 故最大生成树 生成以后 再用lca计算树上两点间的距离 (当然防止生成树是一条链,可以用树的重心作为 ...
- ACM-ICPC 2018 徐州赛区网络预赛 J Maze Designer(最大生成树,倍增lca)
https://nanti.jisuanke.com/t/31462 要求在一个矩形中任意选两个点都有唯一的通路,所以不会建多余的墙. 要求满足上述情况下,建墙的费用最小.理解题意后容易想到首先假设全 ...
- ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer
传送门:https://nanti.jisuanke.com/t/31462 本题是一个树上的问题:结点间路径问题. 给定一个有N×M个结点的网格,并给出结点间建立墙(即拆除边)的代价.花费最小的代价 ...
- ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心)
ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心) Trace 问答问题反馈 只看题面 35.78% 1000ms 262144K There's a beach in t ...
- 计蒜客 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 ...
- ACM-ICPC 2018 徐州赛区网络预赛 B(dp || 博弈(未完成)
传送门 题面: In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl n ...
- 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 ...
- ACM-ICPC 2018 徐州赛区网络预赛 F. Features Track
262144K Morgana is learning computer vision, and he likes cats, too. One day he wants to find the ...
随机推荐
- Python面试笔记四
数据库 1.将name字段添加索引 create index index_emp_name on student(name); 2.查询女生中数学成绩最高的分数 select max(score) f ...
- Hexo自定义页面的方法
原文转自:http://refined-x.com/2017/07/10/Hexo%E8%87%AA%E5%AE%9A%E4%B9%89%E9%A1%B5%E9%9D%A2%E7%9A%84%E6%9 ...
- applicationSettings设置和appsttings
applicationSettings 可以和sttings一样在配置文件中,设置参数.支持定义参数的类型“serializaAs=string”,并可以使用 . 语法. 可以使用.语法
- CF1012A Photo of The Sky
CF1012A Photo of The Sky 有 \(n\) 个打乱的点的 \(x,\ y\) 轴坐标,现在告诉你这 \(2\times n\) 个值,问最小的矩形面积能覆盖住n个点且矩形长和宽分 ...
- keras 的 Deeplabv3+ 实现遇到的问题
代码大佬都已经写好了,具体参考:https://github.com/bonlime/keras-deeplab-v3-plus git clone 下来以后,按照指南要训练自己的数据集,只要设置好自 ...
- redis 初步认识一(下载安装redis)
1.下载redis https://github.com/MicrosoftArchive/redis/releases 2.开启redis服务 3.使用redis 4.redis可视化工具 一 开 ...
- go笔记-限速器(limiter)
参考: https://blog.csdn.net/wdy_yx/article/details/73849713https://www.jianshu.com/p/1ecb513f7632 http ...
- PS调出韩式米黄色室内婚纱照片
原图: Camera Raw打开原图. 光线调整,压暗白色,保留高光细节,少量对比黑色压暗. 降低整体饱和. 曲线调整,压暗高光明度. 减红加青(融合色彩). 中间调,靠近暗部区域加蓝,靠近亮部区域加 ...
- (转)JMeter学习逻辑控制器
JMeter中的Logic Controller用于为Test Plan中的节点添加逻辑控制器. JMeter中的Logic Controller分为两类:一类用来控制Test Plan执行过程中节点 ...
- jmeter beanshell 中使用map
1.使用第三方jar包的时候可以放在lib目录下也可以放在lib/ext目录下,放在这两个目录都可以引用jar包成功,通过引用json的jar包在另个目录都实验过成功. 2.通过学习知道可以在bean ...