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 ...
随机推荐
- Dijango学习_01_pycharm创建应用
一.当初在学dijango的时候,网上的教程非常的杂且多,对于؏؏☝ᖗ乛◡乛ᖘ☝؏؏我们这种初入虎门的小白来说有太多误区 (其实是大佬的操作着实对小白不太友好,原谅我个萌新..2333..) 二.pi ...
- Django 路由层(urlconf)
Django 的路由层(URLconf) URL配置(conf)就像是Django所支撑的网站的目录; 本质就是:URL与调用该URL执行的视图函数的映射表; 通俗的讲:就是用户使用哪个url,URL ...
- Kafka 0.11.0.0 实现 producer的Exactly-once 语义(英文)
Exactly-once Semantics are Possible: Here’s How Kafka Does it I’m thrilled that we have hit an excit ...
- Nginx 配置 和安装
Nginx 博客 web服务器和web框架的关系 web服务器(nginx): 接收HTTP请求(例如www.pythonav.cn/xiaocang.jpg)并返回数据 web服务器,仅仅就是 接收 ...
- 【转】Android开发:Service和Thread的关系
不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会有点让你吃惊,因为Service和Th ...
- 【重磅】FineUIPro基础版免费,是时候和ExtJS说再见了!
三石的新年礼物 9 年了,FineUI(开源版)终于迎来了她的继任者 - FineUIPro(基础版),并且完全免费! FineUIPro(基础版)作为三石奉献给社区的一个礼物,绝对让你心动: 拥 ...
- HBase操作命令总结
1,如何运行HBase 1,如何查找hbase的安装目录 whereis用来查找程序的安装目录.帮助文档等等,如下: whereis hbase 结果如下,目录下一级包含bin的就是hbase的安装目 ...
- css高級技巧
1.鼠標顯示 a:小手cursor:pointer b:默認cursor:default c:勾選文本cursor:text d:拖動cursor:move 2.css三種佈局模型 a.流動模型(默認 ...
- const 本质
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动.对于简单类型的数据(数值.字符串.布尔值),值就保存在变量指向的那个内存地址,因此等同于常量.但对于复合类型的数据( ...
- mongoDB 小练习
1 创建数据库名为 grade > use grade switched to db grade 2 创建集合 class 3 插入若干数据 格式如下{name:xxx,age:xxx,sex: ...