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 ...
随机推荐
- LNMP时,出现502 Bad Gateway的错误提示
因为工作需要,要在ubuntu中安装LNMP环境,在这里,php是最新版本php7.1.一切都进展得很顺利,安装完成后,在浏览器中输入http://127.0.0.1/info.php,出现了502 ...
- Angular安装及创建第一个项目
Angular简介 AngularJS 诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJ ...
- 【Python 18】BMR计算器2.0(数值类型转换与while循环)
1.案例描述 基础代谢率(BMR):我们安静状态下(通常为静卧状态)消耗的最低热量,人的其他活动都建立在这个基础上. 计算公式: BMR(男) = (13.7*体重kg)+(5.0*身高cm)-(6. ...
- 【Teradata】扩容操作步骤
第一章,前期准备(旧系统信息收集) 1.DBScontrol关键信息 DBSCONTROL系统参数是在节点上设置的,其参数直接关系到系统全局,需要慎重设置,新节点的关键参数要与生产库一致或者相容.主要 ...
- centos7下kubernetes(12。kubernetes-service)
Service:定义了一个服务得访问入口地址,前端的应用通过这个入口地址访问其背后得一组由pod副本组成的集群实例: service与后端的pod副本集群之间则是通过label selector来实现 ...
- Django-CRM项目学习(六)-rbac模块(权限组件)
1.rbac权限组件 1.1 模板分析(五表结构) 1.2 模板构建 人物和角色进行多对多绑定,角色与权限进行多对多绑定.其中人物和角色的多对多绑定的操作可以避免相同的人物多重权限的操作. 1.3 数 ...
- 初识服务发现及Consul框架的简单使用
初识服务发现及Consul框架的简单使用 1.什么是服务发现? 服务发现组件记录了(大规模)分布式系统中所有服务的信息,人们或者其它服务可以据此找到这些服务. DNS 就是一个简单的例子. 当然, ...
- 网络安全实验室--SQL注入关
第一关 万能密码:username='or '1'='1'# password=1 即可登录得到flag. 第二关 最基础的注入,order by 判断字段数,然后 union selec ...
- 微信小程序遍历Echarts图表,实现多个饼图
如何在微信小程序中使用Echarts可以看我的另一个教程:点击查看 首先看一个简单的例子 1.wxml文件 <view style='width:100%;height:200rpx'> ...
- win10下ElasticSearch5.5.1与head、Kibana、X-Pack、SQL、IK、PINYIN插件的配置安装
ElasticSearch5.5.1与插件的配置安装 Elasticsearch5.5.1安装: 下载地址https://www.elastic.co/cn/downloads/elasticsear ...