欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Til the Cows Come Home(简单的最短路)

程序员文章站 2022-03-22 22:19:59
...

Til the Cows Come Home
Bessie 在外地,想要在 Farmer John 叫醒她早上挤奶之前回到谷仓尽可能多地睡觉。Bessie 需要她的美容觉,所以她想尽快回来。

Farmer John 的田地中有 N (2 <= N <= 1000) 个地标,唯一编号为 1…N。地标 1 是谷仓;Bessie 整天站立的苹果树树林是 N 的地标。奶牛使用 T (1 <= T <= 2000) 条地标之间不同长度的双向牛道在田间行进。Bessie 对自己的导航能力没有信心,所以一旦开始,她总是从头到尾留在一条小路上。

给定地标之间的小径,确定 Bessie 必须步行才能返回谷仓的最小距离。保证存在一些这样的路由。
输入

  • 第 1 行:两个整数:T 和 N

  • 第 2…T+1 行:每行将一条路径描述为三个空格分隔的整数。前两个整数是路径经过的地标。第三个整数是路径的长度,范围是 1…100。
    输出

  • 第 1 行:单个整数,即 Bessie 从地标 N 到地标 1 必须经过的最小距离
    样本输入
    5 5
    1 2 20
    2 3 30
    3 4 20
    4 5 20
    1 5 100
    样本输出
    90
    暗示
    输入细节:

有五个地标。

输出详细信息:

Bessie 可以沿着路径 4、3、2 和 1 回家。
思路:简单的迪杰斯特拉,不过可能有一个坑,如本来给出
x y 2,后面又给出,x y 20,即重边问题。

#include <cstdio>
#include <queue>
#include <climits>
#include <string.h>
#include <iostream>
using namespace std;
int vist[1005];
int dis[1005];
int e[1005][1005];
int main()
{
	int n,m,x,y,zhi,inf,i;
	while(cin>>m>>n){
		memset(vist,0,sizeof(vist));
		memset(e,0x3f3f3f,sizeof(e));
		inf=e[0][0];
		for(i=1;i<=m;i++){
			scanf("%d%d%d",&x,&y,&zhi);
			if(zhi<e[x][y]){//如果遇到重边,选择最小的边
			e[x][y]=zhi;
			e[y][x]=zhi;
			}	
		}
		for(i=1;i<=n;i++){//dis[i]保存的是起点到i点的最短距离
			dis[i]=e[1][i];
		}
		int cnt=0,d,xiao;
		cnt++;
		vist[1]=1;
		while(cnt<n){//n个点只需要选n-1条边
			xiao=inf;
			d=-1;
			for(i=1;i<=n;i++){
				if(!vist[i]&&xiao>dis[i]){//选则起点到i点最小的边
					xiao=dis[i];
					d=i;
				}
			}
			if(d==-1) break;
			cnt++;
			vist[d]=1;//标记这个点已经选了
			for(i=1;i<=n;i++){
				if(!vist[i]&&e[d][i]+dis[d]<dis[i]){//通过d点到i的距离比直接到i的距离小,所以更新
					dis[i]=e[d][i]+dis[d];
				}
			}
		} 
		printf("%d\n",dis[n]);
	
	}
}