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. 🔥🔥通过访问URL地址,5分钟内渗透你的网站!很刑很可拷!

    今天我来带大家简单渗透一个小破站,通过这个案例,让你深入了解为什么很多公司都需要紧急修复各个中间件的漏洞以及进行URL解析拦截等重要操作.这些措施的目的是为了保护网站和系统的安全性.如果不及时升级和修 ...

  2. IDEA提示无法解析resourse中的方法getResourceAsStream

    一.解决方案 1.错误展示: InputStream inputStream = Resources.getResourceAsStream(resource); 2.报错展示: 报错原因:这是因为找 ...

  3. SpringCore完整学习教程5,入门级别

    本章从第6章开始 6. JSON Spring Boot提供了三个JSON映射库的集成: Gson Jackson JSON-B Jackson是首选的和默认的库. 6.1. Jackson 为Jac ...

  4. [ARC145D] Non Arithmetic Progression Set

    Problem Statement Construct a set $S$ of integers satisfying all of the conditions below. It can be ...

  5. [ABC262F] Erase and Rotate

    Problem Statement You are given a sequence $P = (p_1,p_2,\ldots,p_N)$ that contains $1,2,\ldots,N$ e ...

  6. HDFS存储原理

    冗余数据保存问题: 一个数据块默认被保存三次 好处:1.加快数据传输错误(假如要同时访问数据块1 因为他冗余存储就会有3份 所以会加快数据传输速度) 2.很容易检查数据错误 3.保证数据可靠性 数据的 ...

  7. 有一个正整数N可以分解成若干个正整数之和,问如何分解能使这些数的乘积最大?

    这可真是个有意思的问题,之前好像在刷题的时候也碰到过类似的问题 问题的解决是:我们由均值不等式可以知道,当每个数相等的时候,有乘积最大. 那么所以实际上就是将这个数均分,假如正整数N为 k,假设分成n ...

  8. Selenium等待元素出现

    https://www.selenium.dev/documentation/webdriver/waits/ 有时候我们需要等待网页上的元素出现后才能操作.selenium中可以使用以下几种方法等大 ...

  9. ElasticSearch之Node query cache settings

    对于filter查询,ElasticSearch提供了缓存查询结果的特性,当缓存中存在满足查询条件要求的数据时,直接从缓存中提取查询结果. 对于ElasticSearch节点,该节点上的所有shard ...

  10. cgroup的入门资料

    近期在准备特性的设计文档,按照评审专家的建议,需要排查现有产品中算力资源比如CPU.内存的分配方案,确认现有的硬件款型是否具备充足的资源来启用本特性. 依据前辈提供的建议,检查了产品的部署脚本,发现当 ...