这道题赛时的时候想了一个奇怪的做法但是没过,后来经过Stay_hungry的提示就码了这道题。

雷电必定会在一点处分叉,分别电击地上的两个点,我们只需要枚举这个分叉点。那么怎么算出这个点和目标点的距离呢,很容易可以想到用最短路来求解。在仔细算一下复杂度\(O({V}log{E}+n^2)\) (\(V\)为点的个数 \(E\)为边的个数)

这道题其实可以转化为图论题,就是从起点和两个终点分别跑一遍最短路,然后枚举那个闪电分开的点,在将三个\(dis_x\)(\(x\)为当前枚举的点的编号)加起来,取个\(Min\)就可以了。

细节处理都在代码中

//必须要开 long long 不然电阻R加起来会炸
//但是#define int long long 会MLE
//所以就把几个dis数组开long long就好了 #include <bits/stdc++.h>
#define Reg register
using namespace std;
const int N=1e3+10;
inline long long Min(long long a,long long b) { return a<b?a:b; }
inline int read() {
int x=0,f=0; char c=getchar();
while(!isdigit(c)) f|=(c=='-'),c=getchar();
while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
return f?-x:x;
}
struct node {
int u;
long long d;
inline bool operator <(const node &rhs) const {
return d>rhs.d;
}
} ;
struct Edge {
int next,to,w;
} edge[N*N*6];
int n=read(),m=read(),sx=read(),e1=read(),e2=read(),tot;
long long ans=5e18;
int head[N*N],a[N][N];
long long diss[N*N],dis1[N*N],dis2[N*N];
//建边
inline void Addedge(int u,int v,int w) {
edge[++tot]=(Edge){head[u],v,w};
head[u]=tot;
}
//Dijkstra
inline void Dijkstra(int s,long long *dis) {
for(Reg int i=1;i<=n*m;i++)
dis[i]=5e18;
//将起点的初值设置为这个位置的电阻值
if(s%m)
dis[s]=a[s/m+1][s%m];
else
dis[s]=a[s/m][m];
priority_queue<node>que;
que.push((node){s,0});
while(!que.empty()) {
node front=que.top(); que.pop();
int u=front.u;
// if(d==dis[u])
for(Reg int i=head[u];i;i=edge[i].next) {
int v=edge[i].to,w=edge[i].w;
// cout<<u<<' '<<v<<' '<<w<<'\n';
if(dis[u]+w<dis[v]) {
dis[v]=dis[u]+w;
que.push((node){v,dis[v]});
}
}
}
}
signed main() {
//将网格图转化为有向图
for(Reg int i=1;i<=n;i++)
for(Reg int j=1;j<=m;j++) {
a[i][j]=read();
//将每个点的编号设为从左往右数,从上往下数第几个
//连边时连的是它四周的四个点连向它自己,所以边权是为这个点的电阻值
if(j>1)//这是防止向上一个网格连的时候越界,下同
Addedge((i-1)*m+j-1,(i-1)*m+j,a[i][j]);
if(j<m)
Addedge((i-1)*m+j+1,(i-1)*m+j,a[i][j]);
if(i>1)
Addedge((i-2)*m+j,(i-1)*m+j,a[i][j]);
if(i<n)
Addedge(i*m+j,(i-1)*m+j,a[i][j]);
}
Dijkstra(sx,diss)/*,puts("---")*/,Dijkstra(m*(n-1)+e1,dis1)/*,puts("---")*/,Dijkstra(m*(n-1)+e2,dis2);
//跑三遍Dijkstra
//枚举中间点
for(Reg int i=1;i<=n;i++)
for(Reg int j=1;j<=m;j++)
//因为中间点会被计算三次,所以要减去两次
ans=Min(ans,diss[(i-1)*m+j]+dis1[(i-1)*m+j]+dis2[(i-1)*m+j]-2*a[i][j])/*,printf("I=%d,J=%d,Dis=%d,%d,%d\n",i,j,diss[(i-1)*m+j],dis1[(i-1)*m+j],dis2[(i-1)*m+j])*/;
cout<<ans<<'\n';
return 0;
}

Luogu P6833 【[Cnoi2020]雷雨】的更多相关文章

  1. [Cnoi2020]线性生物

    期望入门题.但是我不会做. 考虑设\(E_{x\to{x+1}}\)为\(x\)到\(x+1\)点的期望步数. 则\(ans = \sum_{i = 0}^{n} E_{x\to{x+1}}\) 知\ ...

  2. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

  3. luogu p1268 树的重量——构造,真正考验编程能力

    题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...

  4. [luogu P2170] 选学霸(并查集+dp)

    题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...

  5. [luogu P2647] 最大收益(贪心+dp)

    题目传送门:https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品. ...

  6. Luogu 考前模拟Round. 1

    A.情书 题目:http://www.luogu.org/problem/show?pid=2264 赛中:sb题,直接暴力匹配就行了,注意一下读入和最后一句话的分句 赛后:卧槽 怎么只有40 B.小 ...

  7. luogu P2580 于是他错误的点名开始了

    luogu  P2580 于是他错误的点名开始了 https://www.luogu.org/problem/show?pid=2580 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 他会一边 ...

  8. CJOJ 1331 【HNOI2011】数学作业 / Luogu 3216 【HNOI2011】数学作业 / HYSBZ 2326 数学作业(递推,矩阵)

    CJOJ 1331 [HNOI2011]数学作业 / Luogu 3216 [HNOI2011]数学作业 / HYSBZ 2326 数学作业(递推,矩阵) Description 小 C 数学成绩优异 ...

  9. Luogu 1349 广义斐波那契数列(递推,矩阵,快速幂)

    Luogu 1349 广义斐波那契数列(递推,矩阵,快速幂) Description 广义的斐波那契数列是指形如\[A_n=p*a_{n-1}+q*a_{n-2}\]的数列.今给定数列的两系数p和q, ...

随机推荐

  1. 多测师讲解python _练习题003_高级讲师肖sir

    python 003作业题:# 1.分别打印100以内的所有偶数和奇数并存入不同的列表当中# 2.请写一段Python代码实现删除一个list = [1, 3, 6, 9, 1, 8]# 里面的重复元 ...

  2. Rust之路(4)——所有权

    [未经书面同意,严禁转载] -- 2020-10-14 -- 所有权是Rust的重中之重(这口气咋像高中数学老师 WTF......). 所有权是指的对内存实际存储的数据的访问权(包括读取和修改),在 ...

  3. 【LWJGL3】LWJGL3的内存分配设计,第一篇,栈上分配

    简介 LWJGL (Lightweight Java Game Library 3),是一个支持OpenGL,OpenAl,Opengl ES,Vulkan等的Java绑定库.<我的世界> ...

  4. windbg加载符号表

    0x00 前言 在使用windbg调试windows中的程序时会经常碰到一些系统的dll里面的一些函数调用,有些函数是没有具体函数名的,这对于调试非常不利,基于此,微软针对windows也发布了很多系 ...

  5. 框架-设备与驱动的拆分及实现-I2C

    目录 前言 笔录草稿 概要 原理及实现方法 IIC 例子实战-驱动 1. 创建文件 2. 创建 I2C 驱动名字列表 3. 组建 I2C 驱动结构体 4. 编写-注册 I2C 驱动函数 5. 创建 I ...

  6. go init执行顺序

    package test import "fmt" // 初始化函数 引入包的时候要先执行 可以重复定义多个 同一个go文件从上到下 多个文件 是按照字符串进行排序 从小到大 执行 ...

  7. postgresql 导出数据库与数据表

    单表导出 pg_dump --host 127.0.0.1 --port 5432 --username "postgres" --role "postgres" ...

  8. javaSE、javaEE、Android知识点总结

    曾今上学时候的一些学习总结,如有错误请大家指出,共同学习. 1. 什么是WebView? WebView是一个使用WebKit引擎的浏览器组件,用来加载网页. 2. WebView中加载网页的两种方式 ...

  9. django—路由相关

    django不同版本的路由配置 django 2之前,配置urlpatterns使用的是url方法 django 2之后,配置urlpatterns使用的是path方法 path与url的区别: ur ...

  10. maven打包插件

    如何把依赖的jar包中的资源抽到当前jar中 maven-compiler-plugin:编译插件,可指定资源jdk版本,前提是当前代码使用的jdk版本 大于或等于 source maven-asse ...