第十二周总结

这周主要学习了Dijkstra算法,后面时间真的是越来越紧了,感觉连知识也整不不太明白时就开始做题,博客也看不了多少,很多思想也没接触过,就只会做一些简单题,感觉也不太明白,这些算法对我来说看就要花费大量的时间,做根本没时间,时间感觉直接不够,那这一个星期就只能浅浅懂一下。

1、​​​​​​[USACO09OCT]Heat Wave G - 洛谷

题意:有一个n个点m条边的无向图,请求出从s到t的最短路长度。

思路:是最基础的题,用来学习Dijkstra算法,

(用数组实现邻接表:这个星期真的是被这个整废了,差不多这一个星期时间都浪费在这个上面了,就是不管咋滴就是看不懂,而且洛谷题和博客大部分都用了,被这个整的题没大看,但是我最后发现了一篇题解,用vector和优先队列实现,这样好理解多了)

inline void add(int a,int b,int c){
    e[++p].nxt = h[a];
    h[a] = p;
    e[p].v = b;
    e[p].w = c;
}

优先队列存图

for(int i=1;i<=m;i++){
        cin>>u>>v>>w;
        pair<int, int> p;   
        p.first = v;    
        p.second = w;
        G[u].push_back(p) ;
        p.first = u;    
        p.second = w;
        G[v].push_back(p) ;
    }

不优化的Dijkstra算法

void dijkstra(int s) {
    for (int i = 0; i <= n; i++) d[i] = INF;

    d[s] = 0;

    for (int i = 1; i <= n; i++) {
        int u = -1;
        for (int j = 1; j <= n; j++) if (!vis[j]) {
            if (u == -1 || d[j] < d[u]) {
                u = j;
            }
        }

        if (u == -1 || d[u] >= INF) break;
        vis[u] = true;
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].first;
            int w = G[u][j].second;
            if (d[v] > d[u] + w) {
                d[v] = d[u] + w;
            }
        }
    }
}

优化的Dijkstra算法

void dijkstra(int s) {
    for (int i = 0; i <= n; i++) d[i] = INF;

    d[s] = 0;
    priority_queue<pair<int, int> > q;
    q.push(make_pair(0, s));

    while (q.size()) {
        int u = q.top().second;
        q.pop();

        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].first;
            int w = G[u][i].second;
            if (d[v] > d[u] + w) {
                d[v] = d[u] + w;
                q.push(make_pair(-d[v], v));
            }
        }
    }
}

2、确实这个星期因为一直搞不懂用矩阵来实现邻接表,故没有太多时间去独立思考,

我就从网上搜寻一些知识点进行学习来弥补这个星期的空缺:

Dijkstra算法理解:

1、Dijkstra算法一般是用来解决单源最短路径问题(指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”。)

2、其时间复杂度仅为O(n^2),并且非常高效,甚至可以优化成O(nlog2n),优先队列。

3、Dijkstra算法中权值只能为正数,若权值为负数则不能使用该算法。(权值即图各个边所赋予的值)

Floyd算法理解:

1、用与求任意的两点的最短距离的算法,而dijstra算法是求已知一点到未知的一点的距离,或者是已知的两点的距离所以要分清这两种求最短路的算法的区别

2.实现原理:map[a][b](a到b的距离)一定是它本身或者是当前的各个的最短路通过 k节点连接(map[i][k]+map[k][j])

3.状态转移方程:map[i][j]=min(map[i][k]+map[k][j],map[i][j]);

对于spfa其算法本质是:
设立一个先进先出的队列q用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。

总结一下吧,这个星期学的少了,就想通过看博客来弥补一下,因为之前一直都是看洛谷上的题,然后再做,现在意识到可能不太适合我,我应该一开始看一些简单的、总结比较好的博客,来让我快速进入新专题的学习,下个星期学习贪心的时候一定要注意这个问题,信息检索能力确实也是一个好的东西,实在是应该加强。现在确实感觉学不太动了,尽管这些算法都有模板可循,但是我无法很好的读懂它,就是感觉难度加大,无法进行深入的学习,这个星期过去也就意味着这个专题的过去,下个星期开始学贪心,希望会好一点,在结课之前我还是会尽力而为,去做好每份要求的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值