猫史档案馆


[每日不刷通天塔 萌新也能懂算法] 【图论】无向图的最短路径

用户:ZH-Y-QZH-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 页 / 共 1下一页
ZH-Y-QZH-Y-Q

center_image

点赞0


评论


­­­­­­­­­­­­­­

我这个萌新怎么办

点赞2


评论


520669已退猫520669已退猫

啊!!大佬膜拜

点赞1


评论


ZH-Y-QZH-Y-Q

タイトルの説明 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


评论


ZH-Y-QZH-Y-Q

喵d

点赞0


评论