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. 【iOS】tableView:cellForRowAtIndexPath: 方法未调用

    今天遇到这个问题, UITableView 的代理方法 tableView:cellForRowAtIndexPath: - (UITableViewCell *)tableView:(UITable ...

  2. 并发栅栏CyclicBarrier---简单问2

    并发栅栏CyclicBarrier---简单问 背景:前几天在网上看到关于Java并发包java.concurrent中一个连环炮的面试题,整理下以备不时之需. CyclicBarrier简介: 栅栏 ...

  3. Hexo结合github制作博客

    https://blog.csdn.net/Hoshea_chx/article/details/78826689 hexo(themes) vuePress jekylly

  4. 关于http 500错误的小结分享

    一般情况下,http 500内部服务器(HTTP-Internal Server Error)错误说明IIS服务器无法解析ASP代码,访问一个静态页面试试是否也出现这个问题. 如果访问静态页面没问题, ...

  5. 携程 Apollo 配置中心传统 .NET 项目集成实践

    官方文档存在的问题 可能由于 Apollo 配置中心的客户端源码一直处于更新中,导致其相关文档有些跟不上节奏,部分文档写的不规范,很容易给做对接的新手朋友造成误导. 比如,我在参考如下两个文档使用传统 ...

  6. 分布式ID系列(3)——数据库自增ID机制适合做分布式ID吗

    数据库自增ID机制原理介绍 在分布式里面,数据库的自增ID机制的主要原理是:数据库自增ID和mysql数据库的replace_into()函数实现的.这里的replace数据库自增ID和mysql数据 ...

  7. Starling 环形进度条实现

    项目初期想实现这个效果来着,查了很多资料(包括式神的<神奇的滤镜>),也没找到完美的实现方法,,当时时间紧迫,就找了传统的进度条来代替实现. 最近偶然心血来潮,查了各方面资料,终于找到实现 ...

  8. 转载 | Sublime text3 实用快捷键整理

    实用快捷键 Ctrl+Shift+P:打开命令面板Ctrl+P:搜索项目中的文件Ctrl+G:跳转到第几行Ctrl+W:关闭当前打开文件Ctrl+Shift+W:关闭所有打开文件Ctrl+Shift+ ...

  9. 利用hash或history实现单页面路由

    目录 html代码 css代码 JavaScript代码 hash方式 history 方式 浏览器端代码 服务器端 在chrome(版本 70.0.3538.110)测试正常 编写涉及:css, h ...

  10. Redis简单梳理及集群配置

    **REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵 ...