UVA10986 - 最短路

1.题目描述:

题目描述

2.题意概述:

给出n,m,s,t,n表示有n个点,m表示有m条边,然后给出m行数据表示m条边,每条边的数据有连接两点的序号以及该边的权值,问说从点s到点t的最短路径是多少。

3.解题思路:
分析题目的样列可知,这一题是要用邻接矩阵来存储无向图,所以要注意无向图怎么存储在邻阶表。连接表的横列有N项,纵列也是N项。形成的N*N项每项都被称为边结点,每项都有纵横两个坐标,例如点(N,N-1),表示的就是从第N点向第N-1点有无路径。由于有E条边,自然有E条路径,但是由于无向=双向,所以要乘以2

4.AC代码:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define maxn 20100
#define N 111
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
typedef unsigned long long ull;
struct node
{
	int to, val;
	node(int a, int b) { to = a; val = b; }
};
vector<node> mp[maxn];
int dis[maxn];
bool vis[maxn];
void spfa(int sta, int n)
{
	memset(vis, 0, sizeof(vis));
	fill(dis, dis + n + 1, INF);
	deque<int> q;
	dis[sta] = 0;
	vis[sta] = 1;
	q.push_back(sta);
	while (!q.empty())
	{
		int u = q.front();
		q.pop_front();
		vis[u] = 0;
		int sz = mp[u].size();
		for (int i = 0; i < sz; i++)
		{
			int v = mp[u][i].to;
			int val = mp[u][i].val;
			if (dis[v] > dis[u] + val)
			{
				dis[v] = dis[u] + val;
				if (!vis[v])
				{
					vis[v] = 1;
					if (!q.empty() && dis[v] >= dis[q.front()])
						q.push_front(v);
					else
						q.push_back(v);
				}
			}
		}
	}
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	long _begin_time = clock();
#endif
	int t;
	scanf("%d", &t);
	for (int i = 1; i <= t; i++)
	{
		int n, m, s, t;
		scanf("%d%d%d%d", &n, &m, &s, &t);
		for (int i = 0; i < n; i++)
			mp[i].clear();
		while (m--)
		{
			int u, v, w;
			scanf("%d%d%d", &u, &v, &w);
			mp[u].push_back(node(v, w));
			mp[v].push_back(node(u, w));
		}
		spfa(s, n);
		printf("Case #%d: ", i);
		if (dis[t] != INF)
			printf("%d\n", dis[t]);
		else
			puts("unreachable");
	}
#ifndef ONLINE_JUDGE
	long _end_time = clock();
	printf("time = %ld ms.", _end_time - _begin_time);
#endif
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值