UVA10986

来源:互联网 发布:java简单五子棋源代码 编辑:程序博客网 时间:2024/05/17 02:22

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);elseq.push_back(v);}}}}}int main(){#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);long _begin_time = clock();#endifint 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]);elseputs("unreachable");}#ifndef ONLINE_JUDGElong _end_time = clock();printf("time = %ld ms.", _end_time - _begin_time);#endifreturn 0;}

0 0
原创粉丝点击