0基础刷图论最短路 1(从ATcoder 0分到1800分)

ATC最短路1 (本文难度rated 0~ 1000)

题目来源:Atcoder
题目收集:
https://atcoder-tags.herokuapp.com/tags/Graph/Shortest-Path
(里面按tag分类好了Atcoder的所有题目,类似cf)
(访问需要魔法)
这算是一个题单,各位有兴趣可以按照这个顺序来刷。
我的代码仅供参考。
会提示关键性质和步骤。 部分有注释。
洛谷、知乎、可以搜到题解。

文章目录

  • ATC最短路1 (本文难度rated 0~ 1000)
    • 1-**Hands**
    • 2- **Cat Snuke and a Voyage**
    • 3-**Collision** https://atcoder.jp/contests/abc209/tasks/abc209_d
    • 4-**友達の友達**
    • **5-Line++**
    • 6-**Range Flip Find Route**
    • 7- Wall
    • 8-**Our clients, please wait a moment**

1-Hands

https://atcoder.jp/contests/arc109/tasks/arc109_a

思维 / 最短路板子(一道atc的负分题)

这题比下面那些800多的难多了…

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18void slove(){int a,b,x,y;cin>>a>>b>>x>>y;int ans = 0;if(a>b){if(2*x>=y){ //如果直接下楼更方便:ans = (a-b-1)*y + x;}else{ans = (a-b-1)*2*x + x;}}else if(a==b){ans = x;}else{if(2*x>=y){ans = (b-a)*y+x;}else{ans = (b-a)*2*x+x;}}cout<<ans<<endl;
}signed main(){slove();
}

2- Cat Snuke and a Voyage

https://atcoder.jp/contests/abc068/tasks/arc079_a

最短路

弱智题…这种题在atc里居然 rate 609????

最短路都不需要跑…

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18void slove(){int n,m;cin>>n>>m;vector<vector<int>> g(n+1);for(int i=1;i<=m;i++){int u,v;cin>>u>>v;g[u].push_back(v);g[v].push_back(u);}for(auto i:g[1]){for(auto j:g[i]){if(i==n or j==n){cout<<"POSSIBLE"<<endl;return;}}}cout<<"IMPOSSIBLE"<<endl;
}signed main(){slove();
}

3-Collision https://atcoder.jp/contests/abc209/tasks/abc209_d

思维

有点意思

/*
当两个城镇的距离是偶数,说明是在城镇相遇
否则在半路相遇。问题是,如何求出任意两个城镇的距离?
这个问题,在N = 1e5的时候是无解的。所以,我们考虑,如何知道这两个城镇的最短距离是否为偶数?
(一个很重要的能力:根据数据范围判断算法)
(树图常见操作:染色)这个问题可以转换为:
对于每个点,我们给与其相邻的所有点涂上不同的颜色。
因为相邻的话,距离是1,是奇数。然后任意两个点,我们只需要观察是否为同一颜色。
如果它们是同一颜色,说明间距是偶数。*/#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18
const int N = 1e5+7;vector<vector<int>> g(N);
int color[N];void get_color(int u,int fa){for(auto v:g[u]){if(v==fa)continue;color[v] = 1 - color[u];get_color(v,u);}
}
void slove(){int n,q;cin>>n>>q;for(int i=1;i<=n-1;i++){int u,v;cin>>u>>v;g[u].push_back(v);g[v].push_back(u);}get_color(1,-1);while(q--){int u,v;cin>>u>>v;if(color[u]==color[v])cout<<"Town"<<endl;else cout<<"Road"<<endl;}
}signed main(){slove();
}

4-友達の友達

https://atcoder.jp/contests/abc016/tasks/abc016_3

这特么跟最短路有什么关系。

这不是暴力吗?

/*
找到每个点朋友的朋友个数。一共有N个人。对于1.
我们需要标记1的所有儿子。
然后再从1的第一个儿子开始,遍历1的第一个儿子的所有儿子
如果没被标记,那么标记,答案+1然后1算完了话,再重新清空标记,去计算2N<10*/#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18
int n,m;
vector<vector<int>> g(11);
int f[11];
void todo(int id){vector<int> flag(n+1);for(auto v:g[id]){flag[v]=1;}for(auto v:g[id]){for(auto k:g[v]){if(k==id)continue;if(flag[k])continue;flag[k]=1;f[id]++;}}
}void slove(){cin>>n>>m;for(int i=1;i<=m;i++){int u,v;cin>>u>>v;g[u].push_back(v);g[v].push_back(u);}for(int i=1;i<=n;i++){todo(i);}for(int i=1;i<=n;i++){cout<<f[i]<<endl;}
}signed main(){slove();
}

5-Line++

https://atcoder.jp/contests/abc160/tasks/abc160_d

水题

/*
给定一个图。
有N个顶点
每个i = 1,2...,N-1 ,都有 i 与 i+1 连一条边。也就是,这其实是一条链子。然后我们在选两个点,x,y
在他们之间连接一个边。现在问你在这幅图中,任意(i,j)之间的最短距离为k的整数对有多少?K取遍1~n-1N的取值范围是 1e3,所以我们可以n^2 求解每两个点之间的距离。所以,任意两个点之间的距离:
1、走直道: j-i
2、走弯道: |x-i| + 1 +|j-y|*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18
const int N = 2e3+7;
int box[N];
void slove(){int n,x,y;cin>>n>>x>>y;for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){int dist = min(abs(j-i),abs(i-x)+1+abs(j-y));box[dist]++;}}for(int i=1;i<=n-1;i++){cout<<box[i]<<endl;}}signed main(){slove();
}

6-Range Flip Find Route

https://atcoder.jp/contests/agc043/tasks/agc043_a

数字三角形模型dp

这严格意义上不是一道图论,而是一道dp。但是我在刷图论的时候遇到了,那就放过来。

这道题,说的是我们每一次操作可以选择一个任意大小的矩形(最小是1),然后将这里面的所有颜色反转。

而且每次我们只能往下走/往右走。所以引发我想起这个模型。

思考什么时候需要反转?

当$ a[i][j]==a[i-1][j] \ or \ a[i][j]==a[i][j-1] $的时候

我们的翻转次数是与上一个状态一样的。

a [ i ] [ j ] = = ′ . ′ a[i][j]=='.' a[i][j]==.的时候,这个点是不需要反转的,所以反转次数与上一个状态一样。

其他的情况,就需要反转次数+1

然后就是先处理下边界,我因为这个WA了几次

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18int dp[101][101];
char a[101][101];void slove(){int n,m;cin>>n>>m;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];dp[1][1]=(a[1][1]=='#');for(int i=2;i<=n;i++){if(a[i][1]=='.' or a[i][1]==a[i-1][1]) dp[i][1]=dp[i-1][1];else dp[i][1] = dp[i-1][1]+1;}for(int j=2;j<=m;j++){if(a[1][j]=='.' or a[1][j]==a[1][j-1])dp[1][j]=dp[1][j-1];else dp[1][j] = dp[1][j-1]+1;}for(int i=2;i<=n;i++){for(int j=2;j<=m;j++){int tempu = dp[i-1][j]+1;int templ = dp[i][j-1]+1;if(a[i][j]=='.'){tempu = dp[i-1][j];templ = dp[i][j-1];}if(a[i][j]==a[i-1][j]){tempu = dp[i-1][j];}if(a[i][j]==a[i][j-1]){templ = dp[i][j-1];}dp[i][j]=min(templ,tempu);}}cout<<dp[n][m]<<endl;
}signed main(){slove();
}

7- Wall

https://atcoder.jp/contests/abc079/tasks/abc079_d

dijkstra / floyed

思考一个问题:当 i->j 的路径长度 不等于 j-> i 的路径长度的时候。
还能用dijkstra吗可以,不过我们要搞清楚,题目需要我们从谁走到谁?如果是求从起点到起点以外的点,那么我们正向跑一边dijkstra是没问题的。如果是要求别的点,走到起点。
那么显然我们可以通过建立反向图,再从起点跑一边dijkstra通过这个问题,我们可以发现,dij算法是不会“回头的”因为我们通过最小堆的优化,每次拓展的点都是离当前点最近的一点。
如果回头的话,就说明,从u到v,有更短的距离
也就是说,从u走别的路有更短的距离到v
例如 u -> i -> j -> v
那么,i,j 一定会比v先更新。
并且,在他们更新之后,只会通过这条路更新v,不会通过 u->v 更新v
所以,不会回头。

Dijkstra 算法

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18int n,m;
int dist[10];
int c[10][10];
int a[201][201];
bool flag[10];
void dijkstra(){for(int i=0;i<=9;i++)dist[i]=INF;priority_queue<PII,vector<PII>,greater<PII>> q;dist[1]=0;q.push({0,1});while(q.size()){int u = q.top().second;q.pop();if(flag[u])continue;flag[u]=1;for(int i=0;i<=9;i++){if(i==u)continue;if(dist[i]>dist[u]+c[i][u]){dist[i] = dist[u]+c[i][u];q.push({dist[i],i});}}}int ans = 0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i][j]!=-1)ans+=dist[a[i][j]];}}cout<<ans<<endl;
}
void slove(){cin>>n>>m;for(int i=0;i<=9;i++){for(int j=0;j<=9;j++){cin>>c[i][j];}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>a[i][j];}}dijkstra();}signed main(){slove();
}

floyd做法

做法2,floyed做法
用于求出当n较小的时候,图中任意两点的最小距离
时间复杂度O(n^3)有个问题就是,为什么枚举中间点的循环是放在最外面?我们的循环是这样的:for(int k=0;k<=9;k++){for(int i=0;i<=9;i++){for(int j=0;j<=9;j++){dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);}}}如果k放在外层,k是从小到达逐渐增长的。可以发现:dist[i][k]一定在dist[i][j]之前被更新过,dist[k][j]一定在dist[i][j]之前被更新过比如说,k=3 , 而在k=0的时候,所有的dp[i][j]都被更新过一次了。我们使用的都是目前最优秀的状态。如果把k放在里面:for(int i=0;i<=9;i++){for(int j=0;j<=9;j++){for(int k=0;k<=9;k++){dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);}}}显然,当i,j都很小的时候,k已经可以跑到9了。所以 dp[i][k] 并不会在 dp[i][j]被更新前更新。/*
把网格里面,除了-1以外的所有数
转化为1所需要的最小代价之和为多少。已经给了
如果把  i 转化为 j 的最小代价是 c[i][j]只需要跑一边最短路。
求出 i转化为1的最短路即可。*/#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18int dist[10][10];
int n,m;
int a[201][201];
bool flag[201];void slove(){cin>>n>>m;for(int i=0;i<=9;i++){for(int j=0;j<=9;j++){cin>>dist[i][j];}}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];//floyedfor(int k=0;k<=9;k++){for(int i=0;i<=9;i++){for(int j=0;j<=9;j++){dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);}}}int ans =0 ;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i][j]!=-1){//求和ans+=dist[a[i][j]][1];}}}cout<<ans<<endl;}signed main(){slove();
}

8-Our clients, please wait a moment

https://atcoder.jp/contests/abc325/tasks/abc325_e

一点小思考:

有个想法:
dijkstra是求起点到所有点的最短路。那么为什么i,j的最短路不能等于
dist[j] - dist[i] 呢?
很显然的问题就是,1到j的最短路不一定经过i
如果经过i,那么这就是ok的。
/*
有N个城市
你现在要从城市1到达城市N对于城市i和城市j
可以选择乘坐汽车:花费时间:D[i][j]*A
乘坐火车 花费时间:D[i][j]*B+C对于汽车,你可以在半途中,用汽车换成火车。
但是不能由火车换成汽车。一个很简单的办法就是:先求出一遍只乘坐公车的最短路。
然后枚举每个点,开始坐火车。我们还需要去算一遍,火车的最短路。由于此时的边权是对称的。所以,我们可以从n点出发
这样可以算出火车的dist2[i]然后二者相加: dist1[i]+dist[2] =  最短距离*/#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18int n,a,b,c;
int d[1001][1001];
int dist[1001];
int dist2[1001];
bool flag[1001];void dijkstra(){for(int i=0;i<=n;i++)dist[i]=INF;dist[1]=0;priority_queue<PII,vector<PII>,greater<PII>> q;q.push({0,1});while(q.size()){int u = q.top().second;q.pop();if(flag[u])continue;flag[u]=1;for(int i=1;i<=n;i++){if(i==u)continue;int w = d[u][i]*a;if(dist[i]>dist[u]+w){dist[i] = dist[u] + w;q.push({dist[i],i});}}}memset(flag,0,sizeof flag);for(int i=0;i<=n;i++)dist2[i]=INF;dist2[n]=0;priority_queue<PII,vector<PII>,greater<PII>> q2;q2.push({0,n});while(q2.size()){int u = q2.top().second;q2.pop();if(flag[u])continue;flag[u]=1;for(int i=1;i<=n;i++){if(i==u)continue;int w = d[u][i]*b+c;if(dist2[i]>dist2[u]+w){dist2[i] = dist2[u] + w;q2.push({dist2[i],i});}}}int ans = INF ;for(int i=1;i<=n;i++){ans = min(ans,dist[i]+dist2[i]);}cout<<ans<<endl;}void slove(){cin>>n>>a>>b>>c;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>d[i][j];}}dijkstra();
}signed main(){slove();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/817997.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 关闭交换分区(swap)

安装Doris、ElasticSearch等服务的时候&#xff0c;Linux交换分区会给这些服务带来很严重的性能问题&#xff0c;需要在安装之前禁用交换分区。 1 查看交换分区信息 首先&#xff0c;使用 swapon --show 或 cat /proc/swaps 命令来查看当前的交换分区状态。它会列出所有当前启…

【300套】基于Springboot+Vue的Java实战开发项目(附源码+演示视频+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f9e1;今天给大家分享300的Java毕业设计&#xff0c;基于Springbootvue框架&#xff0c;这些项目都经过精心挑选&#xff0c;涵盖了不同的实战主题和用例&#xff0c;可做毕业…

【vue】用vite创建vue项目

前置要求 要有Node.js 1. 用vite创建vue项目 在cmd中&#xff0c;进入一个文件夹 在文件资源管理器上面的文件目录中&#xff0c;输入cmd&#xff0c;回车在cmd中通过cd命令进入对应文件夹 创建项目 npm create vitelatest # 创建项目创建项目过程中的一些选项 Ok to pro…

Fake-SMS恶意软件混淆分析——低代码的时代来了

写在前面的话 在安全社区中&#xff0c;只要聊到开源代码使用方面的话题&#xff0c;就肯定会聊到安全问题。虽然使用开源代码通常会被认为是安全的&#xff0c;但我们需要清楚的是&#xff0c;与非FOSS&#xff08;自由与开源软件&#xff09;解决方案相比&#xff0c;开源软…

Hive on spark源码编译与调优

文章目录 一、编译环境准备1、hadoop和hive安装2、编译环境搭建3、Hive on Spark配置 二、Hive相关问题1、Hadoop和Hive的兼容性问题1.1 问题描述1.2 解决思路1.3 修改并编译Hive源码 2、Hive插入数据StatsTask失败问题3.1 问题描述3.2 解决思路 3、Hive和Spark兼容性问题3.1 问…

【Android surface 】二:源码分析App的surface创建过程

文章目录 画布surfaceViewRoot的创建&setView分析setViewrequestLayoutViewRoot和WMS的关系 activity的UI绘制draw surfacejni层分析Surface无参构造SurfaceSessionSurfaceSession_init surface的有参构造Surface_copyFromSurface_writeToParcelSurface_readFromParcel 总结…

【Hive上篇: 一篇文章带你使用Hive!深入了解Hive!学会Hive!】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;本篇文章主要分享的是大数据开发中hive的相关技术&#xff0c;什么是Hive&#xff1f;怎么使用Hive&#xff1f;怎么安装部署&#xff1f;希望大家看完这篇文章会有所帮助。也希望大家能够…

运筹优化库Qaekwy入门——以指派问题为例

文章目录 1. 什么是 Qaekwy?2. 安装方法(Windows)3. 指派问题3.1 描述问题3.2 建立问题模型3.3 模型求解1. 什么是 Qaekwy? 在 2023 年 9 月 Github 上开源了一个新的优化求解器 Qaekwy,根据官方对 Qaekey 的介绍,该求解器严格来说是一个 Python 客户端,通过 Python 接…

Depth maps转点云

前言 本文主要记录一下如何可视化相机位姿&#xff0c;如何用Blender得到的深度图反投影到3D空间&#xff0c;得到相应的点云。 Refernce https://github.com/colmap/colmap/issues/1106 https://github.com/IntelRealSense/librealsense/issues/12090 https://medium.com/yod…

【详细讲解下Photoshop】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

大模型推理过程

在人工智能领域&#xff0c;尤其是在机器学习和深度学习中&#xff0c;“推理”&#xff08;Inference&#xff09;是指使用训练好的模型来进行预测或决策的过程。在模型被训练以学习数据的特征和模式之后&#xff0c;推理就是将实际的数据输入模型&#xff0c;以获得输出结果的…

鸿蒙 Failed :entry:default@CompileResource...

Failed :entry:defaultCompileResource... media 文件夹下有文件夹或者图片名称包含中文字符 rawfile 文件夹下文件名称、图片名称不能包含中文字符

地理空间分析中的深度学习应用

深度学习与地理信息系统 (GIS) 的结合彻底改变了地理空间分析和遥感的格局。这种结合将遥感和地理空间分析领域带到了全球研究人员和科学家的前沿。 深度学习是机器学习的一个复杂子集&#xff08;更多关于机器学习的内容&#xff0c;请参阅我的其他文章&#xff09;&#xff0…

【JVM】JVM调优可配置参数及配置时机和原则

接着上一篇不同场景下JVM调优手段及代码优化建议,接着来JVM调优可配置参数及配置时机和原则。以在JDK 8为例&#xff0c;JVM提供了一系列的可配置参数&#xff0c;这些参数可以帮助开发者和系统管理员针对不同的应用场景进行性能调优。以下是按维度划分的一些关键参数及其用途、…

JS中的常见二进制数据格式

格式描述用途示例ArrayBuffer固定长度的二进制数据缓冲区&#xff0c;不直接操作具体的数据&#xff0c;而是通过类型数组或DataView对象来读写用于存储和处理大量的二进制数据&#xff0c;如文件、图像等let buffer new ArrayBuffer(16);TypedArray基于ArrayBuffer对象的视图…

绿色地狱steam叫什么 绿色地狱steam怎么搜

绿色地狱steam叫什么 绿色地狱steam怎么搜 《绿色地狱》是一款以亚马逊雨林为背景的开放世界生存模拟游戏。玩家们扮演一名被困在丛林中的冒险者&#xff0c;玩家在游戏内需要学习采集资源、建造庇护所、狩猎和烹饪食物&#xff0c;同时要面对丛林中的危险和挑战&#xff0c;…

LeetCode 707.设计链表

LeetCode 707.设计链表 1、题目 力扣题目链接&#xff1a;707. 设计链表 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。…

太好玩了,我用 Python 做了一个 ChatGPT 机器人

毫无疑问&#xff0c;ChatGPT 已经是当下编程圈最火的话题之一&#xff0c;它不仅能够回答各类问题&#xff0c;甚至还能执行代码&#xff01; 或者是变成一只猫 因为它实在是太好玩&#xff0c;我使用Python将ChatGPT改造&#xff0c;可以实现在命令行或者Python代码中调用。…

langchain 链式写法-使用本地 embedding 模型,Faiss 检索

目录 示例代码1 示例代码2 示例代码1 使用本地下载的 embedding 模型去做 embedding&#xff0c;然后从中查相似的 import os from dotenv import load_dotenv from langchain_community.llms import Tongyi load_dotenv(key.env) # 指定加载 env 文件 key os.getenv(DAS…

ansible创建用户账户和更新ansible库的密钥

1.创建⽤户帐户 从 http://materials/user_list.yml 下载要创建的⽤户的列表&#xff0c;并将它保存到 /home/greg/ansible 在本次考试中使⽤在其他位置创建的密码库 /home/greg/ansible/locker.yml 。创建名为 /home/greg/ansible/users.yml 的 playbook &#xff0c;从⽽…