用户:ZH-Y-Q查看:6 回复:5 评论:6 创建时间:2020-05-05T10:01:19
题目描述
求出从1出发到各点的最短路径。
输入
第一行输入n和m,代表n个节点,m条边,(2<n<105,1<m<105)
后面m行,每行有x,y,z,代表x到y的路距离为z
输出
按顶点编号(2-n)各个顶点到顶点1的最短距离
样例输入10 12
1 4 1
1 5 1
1 6 1
4 8 1
4 3 1
3 5 1
5 7 1
3 7 1
6 2 1
7 2 1
7 10 1
2 9 1 样例输出
2
2
1
1
1
2
2
3
3 代码实现
//vector储存图+优先队列
#include<bits/stdc++.h>
using namespace std;
struct Edge{
int v; //终点
int w; //保存每边的边权(距离)
bool operator < (Edge b)const{
return w>b.w; //优先队列(小顶堆)
}
}now,tmp,et,t1,t2;
int n,m,dis[500001],vis[500001];
int const inf=0x3f3f3f;
vector<Edge> es[500001]; //向量保存图
void dijkstra(int s);
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
es[i].clear();
}
while(m--){
int u,v,w;
cin>>u>>v>>w;
t1.v=v;
t1.w=w;
t2.v=u;
t2.w=w;
es[u].push_back(t1); //无向图是双向的
es[v].push_back(t2);
}
dijkstra(1); //调用Dijkstra算法
for(int i=2;i<=n;i++)
cout<<dis[i]<<endl;
return 0;
}
void dijkstra(int s){ //所有顶点到起点距离很大
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
//所有顶点到起点最小距离没有确定
dis[s]=0; //起点到起点距离是0
now.v=s; //一开始起点就是终点
now.w=0; //权值是0
priority_queue<Edge>q; //优先队列
q.push(now); //起点入队列
while(!q.empty()){
now=q.top(); //出优先队列
q.pop();
if(vis[now.v]==1){ //已经被访问过,那么跳过
continue;
}
vis[now.v]=1;
int len=es[now.v].size(); //从now.v出发的边数
for(int i=0;i<len;i++){ //遍历每条边
tmp=es[now.v][i];
if(dis[now.v]+tmp.w<dis[tmp.v]){
dis[tmp.v]=dis[now.v]+tmp.w;
et.v=tmp.v;
et.w=dis[tmp.v]; //修改顶点tmp.v的权为到起点的权(距离)
q.push(et);
}
}
}
}タイトルの説明 1から各ポイントまでの最短経路を見つけます。 入力 最初の行にnノードとmエッジを表すnとmを入力します(2 <n <105,1 <m <105) 以下のm行。各行にはx、y、zがあり、xからyまでの距離はzです。 アウトプット 各頂点から頂点1までの頂点番号(2-n)による最短距離 入力例 10 12 1 4 1 1 5 1 1 6 1 4 8 1 4 3 1 3 5 1 5 7 1 3 7 1 6 2 1 7 2 1 7 10 1 2 9 1 出力例 2 2 1 1 1 2 2 3 3 コードの実装 //ベクターストレージマップ+優先キュー #include <bits / stdc ++。h> 名前空間stdを使用します。 構造体エッジ{ int v; //終点 int w; //各辺のエッジの重み(距離)を保存します bool演算子<(Edge b)const { return w> b.w; //優先キュー(小さなトップヒープ) } }今、ニャーp、et、t1、t2; int n、m、dis [500001]、vis [500001]; int const inf = 0x3f3f3f; vector <Edge> es [500001]; //ベクトル保存マップ void dijkstra(int s); int main(){ cin >> n >> m; for(int i = 1; i <= n; i ++){ es [i] .clear(); } 間(m-){ int u、v、w; cin >> u >> v >> w; t1.v = v; t1.w = w; t2.v = u; t2.w = w; es [u] .push_back(t1); //無向グラフは双方向です es [v] .push_back(t2); } dijkstra(1); // Dijkstraアルゴリズムを呼び出す for(int i = 2; i <= n; i ++) cout << dis [i] << endl; 0を返します。 } void dijkstra(int s){//すべての頂点と開始点の間の距離が大きい memset(dis、inf、sizeof(dis)); memset(vis、0、sizeof(vis)); //すべての頂点と開始点の間の最小距離が決定されていません dis [s] = 0; //開始点から開始点までの距離は0です now.v = s; //開始点は終了点です now.w = 0; //重みは0です priority_queue <Edge> q; //優先キュー q.push(now); //キューを開始します while(!q.empty()){ now = q.top(); //優先キュー外 q.pop(); if(vis [now.v] == 1){//すでに訪問済みの場合、スキップします 続ける; } vis [now.v] = 1; int len = es [now.v] .size(); // now.vからのエッジの数 for(int i = 0; i <len; i ++){//各エッジをトラバースする Meow p = es [now.v] [i]; if(dis [now.v] +喵p.w <dis [喵p.v]){ dis [喵p.v] = dis [now.v] +喵p.w; et.v = Meow p.v; et.w = dis [喵p.v]; //頂点ニャーp.vの重みを開始点に変更 q.push(et); } } } }
点赞0
评论