Okabe and City

题解:

将行和列也视为一个点。 然后从普通的点走到行/列的点的话,就代表这行/列已经被点亮了。

然后将费用为0的点建上边。

注意讨论(n,m)非亮的情况下。

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
const int M = 6E5 + ;
int x[N], y[N];
vector<int> vx[N], vy[N];
bool cmpx(int a, int b){
return y[a] < y[b];
}
bool cmpy(int a, int b){
return x[a] < x[b];
}
int head[N], to[M], nt[M], ct[M], tot;
void add(int u, int v, int w){
to[tot] = v; ct[tot] = w;
nt[tot] = head[u]; head[u] = tot++;
}
priority_queue<pll, vector<pll>, greater<pll> > pq;
int dis[N];
int main(){
memset(head, -, sizeof head);
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
int f = , b;
for(int i = ; i <= k; ++i){
scanf("%d%d", &x[i], &y[i]);
if(x[i] == n && y[i] == m) f = i;
if(x[i] == && y[i] == ) b = i;
vx[x[i]].pb(i);
vy[y[i]].pb(i);
}
for(int i = ; i <= n; ++i){
sort(vx[i].begin(), vx[i].end(), cmpx);
for(int j = ; j < vx[i].size(); ++j){
int p = vx[i][j-], n = vx[i][j];
if(y[n] == y[p] + ) {
add(n, p, );
add(p, n, );
}
}
for(int x : vx[i]){
if(i>) add(x, k+i-, );
add(x, k+i, );
if(i<n) add(x, k+i+, );
}
for(int x : vx[i]){
add(k+i, x, );
}
if(i > ){
for(int x : vx[i-]){
add(k+i, x, );
}
}
if(i < n){
for(int x : vx[i+]){
add(k+i, x, );
}
}
}
for(int i = ; i <= m; ++i){
sort(vy[i].begin(), vy[i].end(), cmpy);
for(int j = ; j < vy[i].size(); ++j){
int p = vy[i][j-], n = vy[i][j];
if(x[n] == x[p] + ){
add(n, p, );
add(p, n, );
}
}
for(int x : vy[i]){
if(i > ) add(x, k+n+i-, );
add(x, k+n+i, );
if(i < m) add(x, k+n+i+, );
}
for(int x : vy[i]){
add(k+i+n, x, );
}
if(i > ){
for(int x : vy[i-]){
add(k+i+n, x, );
}
}
if(i < n){
for(int x : vy[i+]){
add(k+i+n, x, );
}
}
}
if(!f){
f = k++n+m;
add(k+n, f, );
add(k+n+m, f, );
}
memset(dis, inf, sizeof dis);
pq.push({,b});/// id, c, cost
dis[b] = ;
while(!pq.empty()){
pll now = pq.top();
pq.pop();
int u = now.se, cost = now.fi;
if(dis[u] != cost) continue;
if(u == f){
cout << cost << endl;
return ;
}
for(int i = head[u]; ~i; i = nt[i]){
int v = to[i], w = ct[i];
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
pq.push({dis[v], v});
}
}
}
puts("-1");
return ;
}

CodeForces 821D Okabe and City的更多相关文章

  1. Codeforces 821E Okabe and El Psy Kongroo(矩阵快速幂)

    E. Okabe and El Psy Kongroo time limit per test 2 seconds memory limit per test 256 megabytes input ...

  2. codeforces 821 D. Okabe and City(最短路)

    题目链接:http://codeforces.com/contest/821/problem/D 题意:n*m地图,有k个位置是点亮的,有4个移动方向,每次可以移动到相邻的点亮位置,每次站在初始被点亮 ...

  3. Codeforces 821C - Okabe and Boxes

    821C - Okabe and Boxes 思路:模拟.因为只需要比较栈顶和当前要删除的值就可以了,所以如果栈顶和当前要删除的值不同时,栈就可以清空了(因为下一次的栈顶不可能出现在前面那些值中). ...

  4. CF821 D. Okabe and City 图 最短路

    Link 题意:给出$n*m$大小的地图,已有$k$盏灯亮,人从左上角出发,右下角结束,期间必须走路灯点亮的地方,他可以在任意时刻消耗一枚硬币点亮一行或一列灯,他最多同时点亮一行或一列灯,要想点亮别的 ...

  5. codeforces E. Okabe and El Psy Kongroo(dp+矩阵快速幂)

    题目链接:http://codeforces.com/contest/821/problem/E 题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y- ...

  6. codeforces B. Strongly Connected City(dfs水过)

    题意:有横向和纵向的街道,每个街道只有一个方向,垂直的街道相交会产生一个节点,这样每个节点都有两个方向, 问是否每一个节点都可以由其他的节点到达.... 思路:规律没有想到,直接爆搜!每一个节点dfs ...

  7. Codeforces 821E Okabe and El Psy Kongroo

    题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y-1)或者(x+1,y)或者(x+1,y+1)三个位子之一.现在一共有N段线段,每条线段都是平行于X ...

  8. Codeforces 821C Okabe and Boxes(模拟)

    题目大意:给你编号为1-n的箱子,放的顺序不定,有n条add指令将箱子放入栈中,有n条remove指令将箱子移除栈,移出去的顺序是从1-n的,至少需要对箱子重新排序几次. 解题思路:可以通过把栈清空表 ...

  9. Codeforces 521 E cycling city

    cf的一道题,非常有意思,题目是问图中是否存在两个点,使得这两个点之间有三条路径,而且三条路径没有公共点. 其实就是判断一下是否为仙人掌就行了,如果不是仙人掌的话肯定就存在,题目难在输出路径上,改了半 ...

随机推荐

  1. ES 23 - 检索和过滤的区别 (query vs. filter)

    目录 1 filter与query示例 1.1 准备测试数据 1.2 搜索测试 2 filter与query的区别 2.1 相关度处理上的不同 2.2 性能上的对比 2.3 对比结论 本文以 ES 6 ...

  2. 【Mac】Mac 使用 zsh 后, mvn 命令无效

    如题-- 解决方法: 将 maven 的环境变量配置放到 .zshrc 文件中. 参考链接: http://ruby-china.org/topics/23158 https://yq.aliyun. ...

  3. K8S 部署 Web UI

    在早期的版本中 Kubernetes可以在 Dashboard 中看到 heapster 提供的一些图表信息, 在后续的版本中会陆续移除掉 heapster,现在更加流行的监控工具是 promethe ...

  4. ansible-yum

    #yum 需要在vim /etc/ansible/hosts里面给执行的主机配置 远程调用python的路径不知道为什么默认值认识python2.6.6 vim /etc/ansible/hosts ...

  5. Python基础总结之第十一天开始【再深入一下函数,重新认识一下】(新手可相互督促)

    感谢最近大家的关注,希望我的学习笔记对大家有帮助!也感谢各位的评论和推荐,请多多指教. 在重新认识函数之前,我们先看两个函数.一个是我们在前面笔记经常用到的print()  :另一个是input() ...

  6. JVM内存结构 VS Java内存模型 VS Java对象模型

    前面几篇文章中, 系统的学习了下JVM内存结构.Java内存模型.Java对象模型, 但是发现自己还是对这三者的概念和区别比较模糊, 傻傻分不清楚.所以就有了这篇文章, 本文主要是对这三个技术点再做一 ...

  7. Docker最简单入门之(一)——介绍和配置Docker

    0. 前言 最近学完了Dokcer,特别记录一下,算是对自己学习成果的一个总结.以便自己能够更好的理解Docker.粗略估计了一下,我大概会分成4个部分,只记录一下常用的操作,至于一些比较难的操作或者 ...

  8. JVM系列(2)- jmap+mat实战内存溢出

    熟悉几个监控JVM的常用命令 1. jps -l 查出当前服务器运行的java进程 --- 2. jinfo用法(结合jps -l查到进程ID) 1).查看最大堆内存:jinfo -flag MaxH ...

  9. Netty学习(六)-LengthFieldBasedFrameDecoder解码器

    在TCP协议中我们知道当我们在接收消息时候,我们如何判断我们一次读取到的包就是整包消息呢,特别是对于使用了长连接和使用了非阻塞I/O的程序.上节我们也说了上层应用协议为了对消息进行区分一般采用4种方式 ...

  10. sublime text 3 15个常用插件介绍

    1.ColorPicker 功能:调色板(需要输入颜色时,可直接选取颜色) 使用:快捷键Windows: ctrl+shift+c 2.Emmet 功能:编码快捷键,前端必备 使用:在输入代码段后,按 ...