出门旅行(tour)AC题解报告

题目描述:

在神奇的 oi 国度,有 n 个城市 m 条双向道路,每条道路连接了两个不同的城市。寒假到了,小 S 决定出门旅游一趟。因为以往跟团旅游多了,这次小 S 决定自驾游。对于自驾游,小 S 最关心的自然是燃油的耗费,为了省钱,小 S 请你帮他找一条最短的路。

输入格式:

第一行两个整数 n,m,表示有 n 个城市和 m 条双向道路。城市从 1..n 编号。
接下来 m 行,每行三个正整数 a,b,c,表示 a 和 b 之间有一条长为 c 的双向道路。a,b 不相同,且 c 不超过 1000
注意:两个城市之间可能会有多条双向道路。
接下来一行两个整数,s,t,表示小 S 本次旅行的出发地和目的地。s,t 不相同。

输出格式:

仅一行一个整数,表示最短的距离。如果不能到达,请输出-1。

样例输入:
3 3
1 2 1
1 3 3
2 3 1
1 3
样例输出:
2

提示:

【样例解释】
1->2->3 即是最优解。
【数据范围】
对于 30%的数据,n<=100,m<=1000
对于 100%的数据,n<=2000,m<=100000

图的存储方式:

存储1:
二维数组,注意存储空间

存储2:
struct data{
	int to, val;
};
vector< data > a[100001];

存储3:
struct node{
	int to,val,next;
}edge[ 400001 ];  //边的数量
int num, head[ 20001 ];   //顶点的数量
void add( int u, int v, int w ){
	edge[ ++num ].to = v;
	edge[ num ].val = w;
	edge[ num ].next = head[u];
	head[ u ] = num;
}

存储4:
和存储3原理一样,只是用多个独立的数组存储
int tot, to[ N ], val[ N ], _next[ N ], _head[ N ];
void add( int x, int y, int z ){
	to[ ++tot ] = y;
	val[ tot ] = z;
	_next[ tot ] = _head[x];
	_head[x] = tot;
}
存储3和存储4称为链式前向星,由某个顶点出发的边的顶点构成一条链,链的尾结点指针(next) 为0。

时间限制: 1000ms
空间限制: 128MB

解析 :

典型的最短路径题目,运用通用的模版改一下就行了。

题解报告:
#include<bits/stdc++.h>
#define N 2001
using namespace std;
int n,m;
vector<pair<int,int>>edges[N];
int vis[N],d[N];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		edges[x].push_back({y,z});
		edges[y].push_back({x,z});
	}
	int s,t;
	cin>>s>>t;
	memset(d,0x3f,sizeof d);
	d[s]=0;
	for(int i=1;i<=n;i++)
	{
		int idx=-1;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j])
				if(idx==-1||d[j]<d[idx])
				idx=j;
		
		}
		vis[idx]=1;
		for(int j=0;j<edges[idx].size();j++)
		{
			int y=edges[idx][j].first;
			if(d[y]>d[idx]+edges[idx][j].second){
				d[y]=d[idx]+edges[idx][j].second;
			}
		}
			
	}
	cout<<(d[t]==0x3f3f3f3f?-1:d[t]);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值