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)的更多相关文章

  1. POJ 2387 Til the Cows Come Home --最短路模板题

    Dijkstra模板题,也可以用Floyd算法. 关于Dijkstra算法有两种写法,只有一点细节不同,思想是一样的. 写法1: #include <iostream> #include ...

  2. POJ 2387 Til the Cows Come Home (最短路径 模版题 三种解法)

    原题链接:Til the Cows Come Home 题目大意:有  个点,给出从  点到  点的距离并且  和  是互相可以抵达的,问从  到  的最短距离. 题目分析:这是一道典型的最短路径模版 ...

  3. POJ 2387 Til the Cows Come Home(最短路模板)

    题目链接:http://poj.org/problem?id=2387 题意:有n个城市点,m条边,求n到1的最短路径.n<=1000; m<=2000 就是一个标准的最短路模板. #in ...

  4. 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 ...

  5. POJ.2387 Til the Cows Come Home (SPFA)

    POJ.2387 Til the Cows Come Home (SPFA) 题意分析 首先给出T和N,T代表边的数量,N代表图中点的数量 图中边是双向边,并不清楚是否有重边,我按有重边写的. 直接跑 ...

  6. POJ 2387 Til the Cows Come Home

    题目链接:http://poj.org/problem?id=2387 Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K ...

  7. 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 ...

  8. POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)

    传送门 Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 46727   Acce ...

  9. 怒学三算法 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 ...

  10. 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 ...

随机推荐

  1. js做四则运算时,精度丢失问题及解决方法

    一.前言:这个问题可以说是程序员必踩的坑,因此网上针对该问题的分析有很多也很详细,解决方法也比较统一,写法也是大同小异,本以为预期效果真能如他们所说是完美的,然而效果却是差强人意. 二.问题:首先,先 ...

  2. 生产实践:Redis与Mysql的数据强一致性方案

    公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 数据库和Redis如何保持强一致性,这篇文章告诉你 目的 Redis和Msql来保持数据同步,并且强一致,以此来提高对应接 ...

  3. 线性代数导论MIT第二章知识点上

    线性代数导论MIT第二章求解线性方程组 2.1--2.2知识点 1.向量与线性方程组 2.不同角度看方程式 也就是矩阵的乘法原型: 以行来看方程式就是原式 以列来看方程式 以矩阵来看方程式 3.消元法 ...

  4. 主界面(零基础适合小白)基础javaweb前端项目实战【包含增删改查,mysql】三

    首先编写sp文件(index.jsp) <%@ page contentType="text/html;charset=UTF-8" language="java& ...

  5. Vue3+Vue-Router+TypeScript+Vite+Element-Plus+Axios+Pinia快速搭建开发框架

    1.环境准备 (1) 首先你得需要安装node和npm 2.环境初始化 (1) 先随意找个文件夹,初始化vite # 安装pnpm npm i -g pnpm # 初始化vite pnpm creat ...

  6. Chrome扩展开发系列开篇

    大家好,我是 dom 哥.这是我关于 Chrome 扩展开发的系列文章,感兴趣的可以 点个小星星. 浏览器现状 研究机构 Statcounter 发布了 2023 年 9 月报告,揭示了有关浏览器的最 ...

  7. POJ1006、hdu1370

    思路:中国剩余定理.纯粹的用暴力求逆元. 1 #include<iostream> 2 #include<string.h> 3 #include<string> ...

  8. 从零开始用 Axios 请求后端接口

    对于前端同学来说,请求后端接口是一个非常通用的东西.在十几年前的时候,我们还用 Ajax 去请求后端接口.但在 2023 年的今天,很多框架都很成熟了,我们有了更加快捷的方式 -- Axios 框架. ...

  9. 设置CentOS7使用代理服务器上网

    用三种方法设置CentOS7使用代理服务器上网 https://zhangyujia.cn/?p=1206 https://www.cnblogs.com/a-du/p/8964048.html 一. ...

  10. CSS3学习笔记-选择器

    在CSS中,选择器是一种指定一个或多个元素的方法.可以根据元素的类型.类.ID.属性等特征来选择元素.CSS3引入了很多新的选择 器,让我们可以更加灵活和精准地选择元素. 下面介绍一些常用的CSS3选 ...