2020 蓝桥杯大学 B 组省赛模拟赛(一) I. 程序设计:最短路(优化+vector存图)

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;
}