您的位置:首页 > 其它

poj 2387 Til the Cows Come Home

2017-05-05 21:21 435 查看
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

【题意】题目其实很简单,但是像我这样的弱鸡还是想了很久,其实算是一个Dij的模板题了,当时看的时候没有认真看,所以做题的时候就是各种不会,还是挺尴尬的。题目大意是有T种关系N个节点,问你每种关系由三个数据构成,分别是两个节点的下标(下标从1开始),和两个下标之间的距离,问你节点N到节点1的最短距离,典型的最短路问题,也就是Dij模板。

【代码】

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int inf=1<<29;//定义一个较大值,也就是不能达到的值
int mat[1010][1010];//用来表示题目中说的那个无向图
int dist[1010];//dist【i】表示第i个节点到1节点的距离
bool vis[1010];//vis【i】表示第i个节点是否搜索过
int t,n,a,b,w;//t表示节点数量,n要找到的节点,a,b相连的节点,w两点距离
void dijkstra(void)
{
int k,minm;
for(int i=1; i<=n; i++)
{
dist[i]=mat[1][i];//初始化dist
vis[i]=false;//一开始所有点都没有来过
}
for(int i=1; i<=n; i++)//将每一个点都遍历一边
{
k=0;//k用来记录下标
minm=inf;//将所求的最小值初始化最大值
for(int j=1; j<=n; j++)
if(!vis[j]&&dist[j]<minm)//点没有来过并且花费小于原始花费
{
minm=dist[j];//记录最小值
k=j;//记录下标
}
vis[k]=true;//这个点现在来了
for(int j=1; j<=n; j++)
if(!vis[j]&&dist[k]+mat[k][j]<dist[j])//考虑k对当前有无影响
dist[j]=dist[k]+mat[k][j];
}
return ;
}
int main()
{
while(~scanf("%d%d",&t,&n))
{
memset(vis,false,sizeof(vis));
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
mat[i][j]=inf;//首先假设所有点不能直达也就是距离无穷远
for(int i=1; i<=t; i++)
{
scanf("%d%d%d",&a,&b,&w);
if(w<mat[a][b])//可能有两条边连接a和b,我们只选取最短的
mat[b][a]=mat[a][b]=w;
}
dijkstra();
printf("%d\n",dist
);
}
return 0;
}


【分析】其实最开始的时候我一直有一点没有弄明白一个地方就是:函数里面第三个for的左右,开始的想法是找出到1最短的一个点,所以认为这个for应该放在外面而不是嵌套在里面,后来明白过来是因为最短的点会不断的更新,所以这个点并不能确定下来。还有就是对这种方法可行性的一点看法

:因为最短的路径只可能有两种方法:直接过去,或者借助某些点过去,所以最短的一定是确定了的,就不用再考虑最短的是否会再改变了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj