POJ 2387 Til the Cows Come Home(最短路板子题,Dijkstra算法, spfa算法,Floyd算法,深搜DFS)
Til the Cows Come Home
| Time Limit: 1000MS | Memory Limit: 65536K | |
|---|---|---|
| Total Submissions: 43861 | Accepted: 14902 |
Description
Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessie needs her beauty sleep, so she wants to get back as quickly as possible.
Farmer John's field has N (2 <= N <= 1000) landmarks in it, uniquely numbered 1..N. Landmark 1 is the barn; the apple tree grove in which Bessie stands all day is landmark N. Cows travel in the field using T (1 <= T <= 2000) bidirectional cow-trails of various lengths between the landmarks. Bessie is not confident of her navigation ability, so she always stays on a trail from its start to its end once she starts it.
Given the trails between the landmarks, determine the minimum distance Bessie must walk to get back to the barn. It is guaranteed that some such route exists.
Input
* Line 1: Two integers: T and N
* Lines 2..T+1: Each line describes a trail as three space-separated integers. The first two integers are the landmarks between which the trail travels. The third integer is the length of the trail, range 1..100.
Output
* Line 1: A single integer, the minimum distance that Bessie must travel to get from landmark N to landmark 1.
Sample Input
5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
Sample Output
90
Hint
INPUT DETAILS:
There are five landmarks.
OUTPUT DETAILS:
Bessie can get home by following trails 4, 3, 2, and 1.
思路:
经典最短路径板子题(模板题)
现在用 Dijkstra算法, spfa(bellman ford)算法, Floyd算法, 深搜DFS都写一遍回顾下
递归DFS(TLE)
使用快读(代码未写出)以后仍T,说明DFS做了很多无用的搜索,在优化搜索的程度上可以进阶学习A*搜索算法
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define ms(a,b) memset(a,b,sizeof(b));
const int inf = 0x3f3f3f3f;
const int N = 1000 + 10;
int map[N][N];
bool book[N];
int minn , n;
void dfs(int index,int step) {
if (index == 1) {
minn = min(minn, step);
return;
}
if (step > minn)return;
for (int i = 1; i <= n; ++i) {
if (!book[i] && map[index][i] != inf) {
book[i] = 1;
dfs(i, step + map[index][i]);
book[i] = 0;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t, t1, t2, w;
while (cin >> t >> n) {
minn = inf;
ms(map,inf);
ms(book,false);
//memset(map, inf, sizeof(map));
//memset(book, false, sizeof(book));
while (t--) {
cin >> t1 >> t2 >> w;
map[t1][t2] = map[t2][t1] = min(map[t1][t2], w);
}
book[n] = 1;
dfs(n, 0);
cout << minn << endl;
}
return 0;
}
dijkstra算法(AC 、79ms)
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int inf=1<<29;
int map[1010][1010];//map[i][j]表示从i-->j的距离
int dist[1010];//dist[i]从v1到i的距离
int vis[1010];//标记有没有被访问过
void dijkstra(int n)
{
int k,min;
for(int i=1; i<=n; i++)
{
dist[i]=map[1][i];
vis[i]=0;
}
for(int i=1; i<=n; i++)//遍历顶点
{
k=0;
min=inf;
for(int j=1; j<=n; j++)
if(vis[j]==0&&dist[j]<min)
{
min=dist[j];
k=j;
}
vis[k]=1;
for(int j=1; j<=n; j++)
if(vis[j]==0&&dist[k]+map[k][j]<dist[j])
dist[j]=dist[k]+map[k][j];//如果找到了通路就加上
}
return;
}
int main()
{
int t,n,a,b,w;
while(~scanf("%d%d",&t,&n))
{
mem(map,0);
mem(vis,0);
mem(dist,0);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
map[i][j]=inf;//初始化为无穷大
for(int i=1; i<=t; i++)
{
scanf("%d%d%d",&a,&b,&w);
if(w<map[a][b])
{
map[a][b]=w;
map[b][a]=map[a][b];//建立无向图
}//这里是判断是否有重边,应为两点之间的路,未必只有一条。
}
dijkstra(n);
printf("%d\n",dist[n]);
}
return 0;
}
堆优化:
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>1
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x,y) memset(x,y,sizeof(x))
#define Maxn 2000+5
#define P pair<int,int>//first最短路径second顶点编号
using namespace std;
int N, M, X;
struct edge
{
int to, cost;
edge(int to, int cost) :to(to), cost(cost) {}
};
vector<edge>G[Maxn];//G[i] 从i到G[i].to的距离为cost
int d[Maxn][Maxn];//d[i][j]从i到j的最短距离
void Dijk(int s)
{
priority_queue<P, vector<P>, greater<P> >q;//按first从小到大出队
for (int i = 0; i <= M; i++)
d[s][i] = INF;
d[s][s] = 0;
q.push(P(0, s));
while (!q.empty())
{
P p = q.top();
q.pop();
int v = p.second;//点v
if (d[s][v] < p.first)
continue;
for (int i = 0; i < G[v].size(); i++)
{
edge e = G[v][i];//枚举与v相邻的点
if (d[s][e.to] > d[s][v] + e.cost)
{
d[s][e.to] = d[s][v] + e.cost;
q.push(P(d[s][e.to], e.to));
}
}
}
}
int main()
{
IOS;
while (cin >> N >> M)
{
for (int i = 0; i < N; i++)
{
int x, y, z;
cin >> x >> y >> z;
G[x].push_back(edge(y, z));
G[y].push_back(edge(x, z));
}
Dijk(1);
cout << d[1][M] << endl;
}
return 0;
}
floyd算法(TLE)
#include<cstring>
#include <iostream>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int inf = 1 << 29;
int map[1010][1010];//map[i][j]表示从i-->j的距离
int main()
{
int t, n, a, b, w;
while (~scanf("%d%d", &t, &n))
{
mem(map, 0);
//初始化
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (i == j)
map[i][j] = 0;
else
map[i][j] = inf;//初始化为无穷大
//建立图
for (int i = 1; i <= t; i++){
scanf("%d%d%d", &a, &b, &w);
map[a][b] = map[b][a] = min(w, map[a][b]);//建立无向图
}//这里是判断是否有重边,应为两点之间的路,未必只有一条。
//弗洛伊德(Floyd)核心语句
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (map[i][k] + map[k][j] < map[i][j])
map[i][j] = map[i][k] + map[k][j];
printf("%d\n", map[1][n]);
}
return 0;
}
Bellman ford算法(AC 496ms。。)
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
typedef long long ll;
//typedef unsigned long long ull;
using namespace std;
const int N = 1005, T = 4005;
int n, t;
int dis[N];
vector<vector<int> > gra(T, vector<int> (3)); //邻接表存储图
const int inf = 1 << 29;
void bellmanford() {
for (int i = 1; i <= n; ++i) {
dis[i] = inf;
}
dis[1] = 0;
for (int i = 1; i < n; ++i) {
for (int j = 1; j <= t * 2; ++j) {
dis[gra[j][1]] = min(dis[gra[j][1]], dis[gra[j][0]] + gra[j][2]);
}
}
}
int main() {
scanf("%d%d", &t, &n);
for (int i = 0, index = 1; i < t; ++i) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
gra[index][0] = a, gra[index][1] = b, gra[index][2] = c; ++index;
gra[index][1] = a, gra[index][0] = b, gra[index][2] = c; ++index;
}
bellmanford();
printf("%d\n", dis[n]);
return 0;
}
spfa队列优化(bfs、AC 79ms)
//spfa
#include <vector>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
const int N = 1005, T = 4005;
int n, t;
int dis[N], vis[N]; //dis数组存单元源点到其他各个点的距离
//vis存顶点v是否已经在队列当中以减少不必要的操作
vector<int> to[N], edge[N]; //邻接表分别存以i为下标的邻接的顶点和权值
const int inf = 1 << 29;
void spfa() {
queue<int> q;
for (int i = 1; i <= n; ++i) {
dis[i] = inf;
}
dis[1] = 0;
q.push(1);
while (!q.empty()) {
int u = q.front(); q.pop();
vis[u] = false;
for (int i = 0; i < to[u].size(); ++i) { //遍历邻接的顶点
int v = to[u][i], w = edge[u][i];
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
if (!vis[v]) {
vis[v] = true;
q.push(v);
}
}
}
}
}
int main() {
scanf("%d%d", &t, &n);
for (int i = 0; i < t; ++i) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
//无向图
to[a].push_back(b); edge[a].push_back(c);
to[b].push_back(a); edge[b].push_back(c);
}
spfa();
printf("%d\n", dis[n]);
return 0;
}
写完几种模板以后分析一下时间复杂度

参考资料
- 资料出自《啊哈算法》
POJ 2387 Til the Cows Come Home(最短路板子题,Dijkstra算法, spfa算法,Floyd算法,深搜DFS)的更多相关文章
- POJ 2387 Til the Cows Come Home --最短路模板题
Dijkstra模板题,也可以用Floyd算法. 关于Dijkstra算法有两种写法,只有一点细节不同,思想是一样的. 写法1: #include <iostream> #include ...
- POJ 2387 Til the Cows Come Home (最短路径 模版题 三种解法)
原题链接:Til the Cows Come Home 题目大意:有 个点,给出从 点到 点的距离并且 和 是互相可以抵达的,问从 到 的最短距离. 题目分析:这是一道典型的最短路径模版 ...
- POJ 2387 Til the Cows Come Home(最短路模板)
题目链接:http://poj.org/problem?id=2387 题意:有n个城市点,m条边,求n到1的最短路径.n<=1000; m<=2000 就是一个标准的最短路模板. #in ...
- POJ 2387 Til the Cows Come Home (图论,最短路径)
POJ 2387 Til the Cows Come Home (图论,最短路径) Description Bessie is out in the field and wants to get ba ...
- POJ.2387 Til the Cows Come Home (SPFA)
POJ.2387 Til the Cows Come Home (SPFA) 题意分析 首先给出T和N,T代表边的数量,N代表图中点的数量 图中边是双向边,并不清楚是否有重边,我按有重边写的. 直接跑 ...
- POJ 2387 Til the Cows Come Home
题目链接:http://poj.org/problem?id=2387 Til the Cows Come Home Time Limit: 1000MS Memory Limit: 65536K ...
- POJ 2387 Til the Cows Come Home(模板——Dijkstra算法)
题目连接: http://poj.org/problem?id=2387 Description Bessie is out in the field and wants to get back to ...
- POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)
传送门 Til the Cows Come Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 46727 Acce ...
- 怒学三算法 POJ 2387 Til the Cows Come Home (Bellman_Ford || Dijkstra || SPFA)
Til the Cows Come Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33015 Accepted ...
- POJ 2387 Til the Cows Come Home (最短路 dijkstra)
Til the Cows Come Home 题目链接: http://acm.hust.edu.cn/vjudge/contest/66569#problem/A Description Bessi ...
随机推荐
- 请查收,本周刷屏的两大热点「GitHub 热点速览」
如果你逛 HackerNews 或者是推特,你一定会被 multipleWindow3dScene 这个跨窗口渲染项目的成果刷屏,毕竟国内的技术平台上也出现了不少的模仿项目.另外一个热点,便是你在白板 ...
- IIS安装与配置
一.环境介绍 Windows Server 2019 64位 标准版 二.IIS安装 2.1.打开服务器管理器,单击添加角色和功能 在Windows Server 2019 服务器管理中,点击角色和功 ...
- [Python急救站]文件管理工具
对于一个程序员,有时候文件太多,忘记放哪里了,那有没有一个可以帮你定位到文件的文件管理工具呢,抱着这样的想法,我做了以下这个代码,可以快速定位找到文件所在位置. import os import tk ...
- C++ Qt开发:LineEdit单行输入组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍LineEdi ...
- Java并发(十八)----常见线程安全类及实例分析
1.常见线程安全类 String Integer StringBuffer Random Vector Hashtable java.util.concurrent (JUC)包下的类 这里说它们是线 ...
- Git日志的相关操作
显示日志 最单纯的日志命令 git log 单条显示 git log -条数 # 例如 git log -2 显示两条 提交信息单行输出 git log --oneline 日志图表显示 git lo ...
- 云端开炉,线上训练,Bert-vits2-v2.2云端线上训练和推理实践(基于GoogleColab)
假如我们一定要说深度学习入门会有一定的门槛,那么设备成本是一个无法避开的话题.深度学习模型通常需要大量的计算资源来进行训练和推理.较大规模的深度学习模型和复杂的数据集需要更高的计算能力才能进行有效的训 ...
- 太牛叉了!国产 AI 智能体惊艳问世,全面致敬 FastGPT!
太震撼了!太厉害了!昆仑万维正式发布了「天工 SkyAgents」平台,助力大模型走入千家万户.你听听,这个名字一听就有一种巧夺天工的感觉,技艺那是相当的高超. 这个平台基于昆仑万维「天工大模型」打造 ...
- Java并发(二十一)----wait notify介绍
1.小故事 - 为什么需要 wait 由于条件不满足(没烟干不了活啊,等小M把烟送过来),小南不能继续进行计算 但小南如果一直占用着锁,其它人就得一直阻塞,效率太低 于是老王单开了一间休息室(调用 w ...
- python 图片相关
python 图片相关 本篇介绍两种方式来打开图片. 1: 使用matplotlib #!/usr/bin/python3 # -*- coding: UTF-8 -*- ""&q ...