1. 程式人生 > 實用技巧 >2020 藍橋杯大學 B 組省賽模擬賽(一) I. 程式設計:最短路(優化+vector存圖)

2020 藍橋杯大學 B 組省賽模擬賽(一) I. 程式設計:最短路(優化+vector存圖)

正反兩次建邊,跑兩次最短路。(主要存個最短路的模板)。

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
ll INF = 1e16+10;
ll dis[N],dis1[N]; // 存兩點之間的距離
bool via[N]; //
用於標記該點是否已經找到最短路 int n, m, a, b; struct node //結構體存邊以及邊的權值 { int to; ll dis; friend bool operator<(node n1, node n2) //過載運算 { return n1.dis > n2.dis; } }; vector<node> vec[N],vec1[N]; //用鄰接表方式存邊,若邊較少可使用鄰接矩陣存邊; priority_queue<struct node> q; //用優先佇列實現可降低時間複雜度。 int
dijstra(int start,vector<node> vec[]) { memset(via, false, sizeof(via)); dis[start] = 0; node t; t.to = start,t.dis = 0; q.push(t); while (!q.empty()) { node now = q.top(); q.pop(); if (!via[now.to]){ via[now.to] = true;
for (int i = 0; i < vec[now.to].size(); i++){ node p=vec[now.to][i]; int to = p.to; ll cost = p.dis + dis[now.to]; //更新與now.to相關聯的點的(p.to)的最短路徑 if (cost < dis[to]){ //更新 dis[to] = cost; node t; t.to = to,t.dis = cost; q.push(t); } } } } } void init() { for (int i = 1; i <= n; i++){ dis[i] = INF; vec[i].clear(); vec1[i].clear(); } } int main() { int t; cin>>t; while(t--){ cin >> n >> m ; init(); for (int i = 1; i <= m; i++){ int u, v, l; cin >> u >> v >> l; node t; t.dis = l,t.to = v; vec[u].push_back(t); t.dis=l,t.to=u; vec1[v].push_back(t); } dijstra(1,vec); for(int i=1; i<=n; i++) dis1[i]=dis[i]; for(int i=1; i<=n; i++) dis[i]=INF; dijstra(1,vec1); ll sum=0; for(int i=1; i<=n; i++){ //cout<<dis1[i]<<" "<<dis[i]<<endl; sum+=dis1[i]+dis[i]; } cout<<sum<<endl; } return 0; }