zoukankan      html  css  js  c++  java
  • 学习记录:Dijstra最短路

    学习记录:Dijstra最短路

    其实Dijstra早学过,这次主要写点用邻接表和堆优化的东西

    想法

    Dijstra的想法其实很简单,维护一个已经达到最短路线的点的集合即可。

    从出发点开始,找到距离出发点最近的那个点加入集合,重复此步骤直至所有点都加入集合即可。

    原因很简单,设出发点为(s),距离(s)最近的点是(i)(Dis[i]<Dis[其他点]+其他点到点i的距离),因此最近的点就加入集合了。

    邻接矩阵实现的Dijstra

    最简单的Dij,但是过不了[洛谷弱化版的模板题][https://www.luogu.com.cn/problem/P3371],空间占用大,但是方便理解Dij的思路

    int Map[maxn][maxn];
    int vis[maxn];
    ll dis[maxn];
    int n, m, s;
    void Dij()
    {
    	for (int i = 1; i <= n; i++)
    		dis[i] = Map[s][i];
    	dis[s] = 0;
    	vis[s] = 1;
    	for (int j = 1; j <= n; j++)
    	{
    		int flag = 0;
    		for (int i = 1; i <= n; i++)
    			if (!vis[i] && (dis[i] < dis[flag] || flag == 0))
    				flag = i;
    		vis[flag] = 1;
    		for (int i = 1; i <= n; i++)
    			if (!vis[i])
    				dis[i] = min(dis[i], dis[flag] + Map[flag][i]);
    	}
    }
    int main()
    {
    	cin >> n >> m >> s;
    	while (m--)
    	{
    		int u, v, w;
    		cin >> u >> v >> w;
    		Map[u][v] = min(w, Map[u][v]);//洛谷的数据最坑的就是有重边...
    	}
    	Dij();
    	for (int i = 1; i <= n; i++)
    		cout << dis[i] << ' ';
    	return 0;
    }
    

    邻接表实现的Dijstra

    这样就可以过模板题了。用的vector实现。

    struct node
    {
    	int to, val;
    	node(int to, int val) : to(to), val(val) {}
    };
    ll n, m, s;
    ll dis[maxn];
    int vis[maxn];
    vector<node> Map[maxn];
    void Dij()
    {
    	for (int i = 0; i <= n; i++)
    		dis[i] = INF;
    	dis[s] = 0;//这里没有初始化dis数组,是因为接下来的循环可以直接初始化
    	for (int k = 0; k < n; k++)
    	{
    		int kk = 0;
    		for (int i = 1; i <= n; i++)
    			if (!vis[i] && dis[i] < dis[kk])
    				kk = i;
    		vis[kk] = 1;
    		for (int i = 0; i < Map[kk].size(); i++)
    			if (dis[Map[kk][i].to] > dis[kk] + Map[kk][i].val)
    				dis[Map[kk][i].to] = dis[kk] + Map[kk][i].val;
    	}
    }
    int main()
    {
    	cin >> n >> m >> s;
    	for (int i = 0, a, b, c; i < m; i++)
    	{
    		cin >> a >> b >> c;
    		Map[a].push_back(node(b, c));
    	}
    	Dij();
    	for (int i = 1; i <= n; i++)
    		cout << dis[i] << ' ';
    	return 0;
    }
    

    堆优化的Dijstra

    struct node
    {
    	int to, val;
    	node(int to, int val) : to(to), val(val) {}
    };
    int n, m, s;
    vector<node> Map[maxn];
    int vis[maxn], dis[maxn];
    
    typedef pair<int, int> P;
    void Dij()
    {
    	priority_queue<P, vector<P>, greater<P>> q;
    	MS(dis, INF);
    	dis[s] = 0;
    	q.push(P(0, s));
    	while (!q.empty())
    	{
    		P p = q.top();
    		q.pop();
    		int index = p.second;
    		if (dis[index] < p.first)
    			continue;
    		for (int i = 0; i < Map[index].size(); i++)
    		{
    			node e = Map[index][i];
    			if (dis[e.to] > dis[index] + e.val)
    			{
    				dis[e.to] = dis[index] + e.val;
    				q.push(P(dis[e.to], e.to));
    			}
    		}
    	}
    }
    int main()
    {
    	cin >> n >> m >> s;
    	for (int i = 1, x, y, z; i <= m; i++)
    	{
    		cin >> x >> y >> z;
    		Map[x].push_back(node(y, z));
    	}
    	Dij();
    	for (int i = 1; i <= n; i++)
    		cout << dis[i] << ' ';
    	return 0;
    }
    
  • 相关阅读:
    unreal-python-howtos
    vscode plugin development
    [uva] 1671 History of Languages
    [codeup] 1128 出租车费
    [codeup] 1126 看电视
    Ubuntu 16.04 + ROS Kinetic 机器人操作系统学习镜像分享与使用安装说明
    (二)ROS系统架构及概念 ROS Architecture and Concepts 以Kinetic为主更新 附课件PPT
    ROS新功能包PlotJuggler绘图
    Winform DevExpress控件库(三) 使用NavBarControl控件定制导航栏
    数据意识崛起,从企业应用看BI软件的未来发展
  • 原文地址:https://www.cnblogs.com/Salty-Fish/p/13439063.html
Copyright © 2011-2022 走看看