题目链接
题意:给出n个点,m条边,求1到n的最短距离的路径.
题解:,大数据,不可使用Dijkstra邻接矩阵和邻接表,都卡空间和时间,直接上堆优化的最短路模板即可~
代码如下:
#include #include #include #include #include #include #include #include #include using namespace std; #define ll long long #define inf 0x3f3f3f3f const int maxn = 1e5 + 10; struct edge {//边 int u, v, w; edge() {} edge(int uu, int vv, int ww) { u = uu; v = vv; w = ww; } }; struct node {//点 int from, i, w; //from=前驱点,i=当前点,w=起点到当前点最短距离 node() {} node(int pp, int ii, int ww) { from = pp; i = ii; w = ww; } bool operator <(const node &a)const { return a.w < w; } }; vectorv[maxn]; bool vis[maxn]; int dis[maxn]; //dis[],pre[]看题目要求加 int pre[maxn]; int n; int dijsktra(int s, int t) { priority_queueq; q.push(node(0, s, 0)); memset(vis, 0, sizeof(vis)); while (!q.empty()) { node p = q.top(); q.pop(); if (p.i == t) {//采用优先队列写法,故当添加该t(终点)时得到的就是最短路了 pre[p.i] = p.from; dis[p.i] = p.w; return p.w; } if (vis[p.i]) continue; //访问过跳过 dis[p.i] = p.w; //可以存到各个点的最短距离 pre[p.i] = p.from; //记录前驱 vis[p.i] = true; for (int i = 0; i < v[p.i].size(); i++) { edge &e = v[p.i][i]; if (vis[e.v]) continue; q.push(node(e.u, e.v, p.w + e.w)); } } return -1; } void dfs(int t, int x, int cnt) { //当前点x到起点t的最短路径 if (pre[x] != 0) { dfs(t, pre[x], cnt + 1); printf("%d%c", x, cnt == 1 ? '\n' : ' '); } else printf("%d%c", t, ' '); } int main() { int m; while (~scanf("%d%d", &n, &m)) { memset(pre, 0, sizeof(pre)); //初始化 for (int i = 1; i <= n; i++) v[i].clear(); while (m--) {//添加无向边 int uu, vv, ww; scanf("%d%d%d", &uu, &vv, &ww); v[uu].push_back(edge(uu, vv, ww)); v[vv].push_back(edge(vv, uu, ww)); } if (dijsktra(1, n) != -1) dfs(1, n, 1); //输出 else cout << "-1" << endl; } }