求最短路
题目描述:
给定一张无向图,求一条经过边数最少的从点1到点N的最短路。
输入格式:
第一行两个整数N,M,表示点数和边数。
接下来M行每行三个整数,表示一条无向边的两端和它的边权。保证点的编号在[1, n]内。
输出格式:
一行两个整数,表示该最短路的长度,以及其经过的边数
如需输出64位整数,请使用cout或者printf("%I64d")。
样例输入:
3 3 1 2 1 2 3 1 1 3 2
样例输出:
2 1
提示:
//虽然1->2->3也是最短路,但是其经过的边数不是最少的。
对于30%:N <= 10
对于60%:N <= 1000
对于100%:N <= 50000, M <= 100000,0 <= 所有的边权 <= 10^9,保证存在从点1到点N的路径。可能有重边,自环。
时间限制:1000ms
空间限制:256MByte
#include<bits/stdc++.h> using namespace std; int n, m; struct enode{ int y, z; enode(int y1, int z1) : y(y1), z(z1) {} }; struct node{ int dis, lu, v; node(int x1, int lu1, int y1) : dis(x1), lu(lu1), v(y1) {} bool operator < (const node &a) const { return dis > a.dis || (dis == a.dis && lu > a.lu); } }; vector<enode> e[50005]; priority_queue<node> q; int dis[50005][2]; bool vis[50005]; int main() { int x, y, z, s, t, v; cin>>n>>m; for(int i = 1; i <= m; i++){ cin>>x>>y>>z; e[x].push_back(enode(y, z)); e[y].push_back(enode(x, z)); } memset(dis, 0x3f3f3f3f, sizeof(dis)); memset(vis, 0, sizeof(vis)); s = 1, t = n; dis[s][0] = dis[s][1] = 0; q.push(node(0, 0, s)); while(!q.empty()){ v = q.top().v; q.pop(); if(vis[v]) continue; vis[v] = 1; for(int i = 0; i < e[v].size(); i++) if(dis[v][0] + e[v][i].z < dis[e[v][i].y][0]){ dis[e[v][i].y][0] = dis[v][0] + e[v][i].z; dis[e[v][i].y][1] = dis[v][1] + 1; q.push(node(dis[e[v][i].y][0], dis[e[v][i].y][1], e[v][i].y)); } else if(dis[v][0] + e[v][i].z == dis[e[v][i].y][0] && dis[e[v][i].y][1] > dis[v][1] +1){ dis[e[v][i].y][1] = dis[v][1] +1; q.push(node(dis[e[v][i].y][0], dis[e[v][i].y][1], e[v][i].y)); } } if(dis[t][0] == 0x3f3f3f3f) cout<<-1<<endl; else cout<<dis[t][0]<<" "<<dis[t][1]<<endl; return 0; }
原文地址:https://www.cnblogs.com/abs27/p/9299293.html
时间: 2024-11-10 03:40:30