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. Kubernetes Gateway API 攻略:解锁集群流量服务新维度!

    Kubernetes Gateway API 刚刚 GA,旨在改进将集群服务暴露给外部的过程.这其中包括一套更标准.更强大的 API资源,用于管理已暴露的服务.在这篇文章中,我将介绍 Gateway ...

  2. 增长实验室-ab分流的流量保护功能介绍

    介绍ab分流的流量保护功能之前,先普及一下ab分流的一些概念和术语 名词解释: 实验:用来验证某个决定请求处理方式的功能或策略的一部分流量,通常用来验证某个功能或策略对系统指标(如PV/UV,CRT, ...

  3. 用友U8与MES系统API接口对接案例分析

    企业数字化转型:轻易云数据集成平台助力 U8 ERP+MES 系统集成 为什么选择数字化转型? 领导层对企业资源规划(ERP)的深刻理解促使了数字化转型的启动. 采用精确的"N+5" ...

  4. [ARC132E] Paw

    题目链接 考虑最后形态,一定是有某一个区间 \([l,r]\) 保持初始的样子, \(l\) 前面都是 <,\(r\) 后面都是 >. 这个区间一定是某两个相邻圆点的位置.设 \(f_i\ ...

  5. Miller_Rabin 学习笔记

    费马小定理:对于任意一个质数满足:\(a^{p-1}\equiv1\pmod p\) 二次探测:对于任意一个奇质数满足:\(x^2\equiv1\pmod p\) 的解为 \(x=1\) 或 \(x= ...

  6. [GDOIpj221B] 数列游戏

    第二题 数列游戏 提交文件: sequence.cpp 输入文件: sequence.in 输出文件: sequence.out 时间空间限制: 1 秒, 256 MB 有一个长度为 \(n\) 的序 ...

  7. [ABC246F] typewriter

    Problem Statement We have a typewriter with $N$ rows. The keys in the $i$-th row from the top can ty ...

  8. RDBMS与Hbase对比 HDFS与HBase对比 Hive与HBase对比

    RDBMS: HBASE: HDFS与HBase对比: Hive与HBase对比: Hive与HBase总结

  9. 痞子衡嵌入式:简析i.MXRT1170 MECC64功能特点及其保护片内OCRAM1,2之道

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170 MECC64功能特点及其保护片内OCRAM1,2之道. ECC是 "Error Correcting C ...

  10. Python趣味入门10:推倒繁琐化烦为简的推导式

    前言 <西部世界>的德洛丽丝进入了MAZE迷宫,假设她需要列出一系列的平方数作为密码,来进入迷宫.在以往的代码生成类似的数列需要使用循环语句,写多行语句.Python有了推导式,只需要1句 ...