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. 【Android】Fresco 初次使用遇到的坑

    初次使用开源框架 Fresco,结果遇到了坑,被虐了半下午--暂且记下. 下面的错误 android.view.InflateException: Binary XML file line #** 报 ...

  2. cookie池的维护

    存储形式: 存储在redis中,“spider_name:username–password":cookie 建立py文件及包含方法: initcookies() 初始化所有账号的cooki ...

  3. wamp不显示文件图标

    wamp不显示文件图标 效果如下图 右键图片"在新的标签页打开图片"后会跳转到404页面,并显示The requested URL /icons/unknown.gif was n ...

  4. 夯实Java基础(八)——代码块

    在Java中代码块指的是使用”{}”括起来的代码称为代码块.代码块一共分为4种:局部代码块,静态代码块,同步代码块,构造代码块. 1.局部代码块 局部代码块就是定义在方法体内部的代码块. public ...

  5. 如何让传统ASP.NET网站在Docker中运行

    本文主要描述如何让传统ASP.NET网站在Docker中运行,侧重Docker image 搭建. 使用条件: Docker for windows 用户切换到Windows 容器模式 Windows ...

  6. java实现发短信功能---腾讯云短信

    目录 java实现发短信功能 前言 开发环境 腾讯云 ---短信 代码 效果 结束语 java实现发短信功能 前言 如今发短信功能已经成为互联网公司的标配,本篇文章将一步步实现java发送短信 考察了 ...

  7. 想转行大数据,开始学习 Hadoop?

    学习大数据首先要了解大数据的学习路线,首先搞清楚先学什么,再学什么,大的学习框架知道了,剩下的就是一步一个脚印踏踏实实从最基础的开始学起. 这里给大家普及一下学习路线:hadoop生态圈——Strom ...

  8. 从原理层面掌握@ModelAttribute的使用(核心原理篇)【一起学Spring MVC】

    每篇一句 我们应该做一个:胸中有蓝图,脚底有计划的人 前言 Spring MVC提供的基于注释的编程模型,极大的简化了web应用的开发,我们都是受益者.比如我们在@RestController标注的C ...

  9. PKI机制总结

    PKI,全称是Public Key Infrastructure,可译为公钥基础设施.它是因特网中节点通信的安全保障机制,HTTPS中的‘S’就来源于PKI. 要去学习一个技术,首先要从它的源头考虑— ...

  10. node爬虫的几种简易实现方式

    说到爬虫大家可能会觉得很NB的东西,可以爬小电影,羞羞图,没错就是这样的.在node爬虫方面,我也是个新人,这篇文章主要是给大家分享几种实现node 爬虫的方式.第一种方式,采用node,js中的 s ...