acwing算法基础课学习记录2(2024.3.29)

对昨日的补充

朴素dijkstra算法
模板:
      1.dist[i]=+INF dist[1]=0
      2. for i 1~n     n次
            t<-不在s中的距离最近的点  (s:当前已经确定最短距离的点存储在内)  n次
            s<-t         n次
            用t更新其他点的距离   总共m次
堆优化版dijkstra
模板:
      1.dist[i]=+INF dist[1]=0
      2. for i 1~n     n次
            t<-不在s中的距离最近的点  (s:当前已经确定最短距离的点存储在内)  朴素:n次  堆:o(1)
            s<-t         n次
            用t更新其他点的距离   朴素:总共m次  堆:多了把更新的点push到堆 总共 用优先队列mlogm次相当于mlogn  用手写堆nlogn

今日把直播课搜索与图论(2)看完了,并且完成了相关的练习题

bellman

bellman-ford算法
        bellman算法 边可以用任意东西来存边,有负权边回路可能无解,但如果负环不在路径上就不影响(spfa算法要求一定没有负环)
        迭代k次的dist数组的数代表从1号点走不超过k条边的最短距离  由此可知如果第n次循环有更新,肯定有一个最短路径是经过n条边,则这个最短路经过n+1个点,推断得知有负环
模板:     for n次
            备份
            for所有边abw
                dist[b]=min(dist[b],dist[a]+w);

题目:有边数限制的最短路

//没啥可说的 边看边写的,和抄的差不多
#include<iostream>
#include<cstring>
using namespace std;
const int  N=10010;
struct Edge{
    int a,b,c;
}edge[N];
int n,m,k;
int dist[510],backup[510];
int bell(){
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    for(int i=0;i<k;i++){
        memcpy(backup,dist,sizeof dist);
        for(int j=0;j<m;j++){
            dist[edge[j].b]=min(dist[edge[j].b],backup[edge[j].a]+edge[j].c);
        }
    }
    return dist[n];
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        edge[i].a=x,edge[i].b=y,edge[i].c=z;
    }
    bell();
    if(dist[n]>0x3f3f3f3f/2)cout<<"impossible";
    else cout<<dist[n];

}

spfa算法

spfa算法
模板:
      queue<-1
      while queue不空
           t<-q.front q.pop
           用t遍历所有出边b
             if(b不在队列)  queue<-b

题目:

spfa求最短路

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=100010;
int h[N],e[N],ne[N],w[N],idx;
int n,m;
int dist[N];
int st[N];
void add(int a,int b,int c){
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
void spfa(){
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    queue<int>q;
    q.push(1);
    st[1]=1;
    while(q.size()){
        int t=q.front();
        q.pop();
        st[t]=0;

        for(int j=h[t];j!=-1;j=ne[j]){
            if(dist[e[j]]>dist[t]+w[j]){
                dist[e[j]]=dist[t]+w[j];
                if(st[e[j]])continue;
                q.push(e[j]);
                st[e[j]]=1;
            }
        }

    }
    return;
}
int main(){
    memset(h,-1,sizeof h);
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
    }
    spfa();
    if(dist[n]==0x3f3f3f3f)cout<<"impossible";
    else cout<<dist[n];

}

spfa判断负环

//误打误撞提交上对了,和模板区别挺大的,看不懂 以后再想想吧,先按照模板写
//模板就不贴了
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=100010;
int h[N],e[N],ne[N],w[N],idx;
int n,m;
int dist[N];
int st[N];
void add(int a,int b,int c){
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
int cnt[N];
int spfa(){
    // memset(dist,0x3f,sizeof dist);
    memset(st,1,sizeof st);
    dist[1]=0;
    queue<int>q;
    // q.push(1);
    st[1]=1;
    for(int i=1;i<=n;i++)q.push(i);
    while(q.size()){
        int t=q.front();
        q.pop();
        st[t]=0;

        for(int j=h[t];j!=-1;j=ne[j]){
            if(dist[e[j]]>dist[t]+w[j]){
                dist[e[j]]=dist[t]+w[j];
                if(st[e[j]])continue;
                q.push(e[j]);
                st[e[j]]=1;
                cnt[e[j]]++;
                if(cnt[e[j]]>=n-1)return -1;
            }
        }

    }
    return 0;
}
int main(){
    memset(h,-1,sizeof h);
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
    }

    if(spfa()==-1)cout<<"Yes";
    else cout<<"No";

}

floyd算法 题目:Floyd求最短路

#include<iostream>
using namespace std;
int s[210][210];
int n,m,q;
void floyd(){
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                s[i][j]=min(s[i][j],s[i][k]+s[k][j]);
            }
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            if(i==j)s[i][j]=0;
            else s[i][j]=1e9;
        }
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(z<s[x][y])s[x][y]=z;
    }
    floyd();
    while(q--){
        int x,y;
        scanf("%d%d",&x,&y);
        if(s[x][y]>1e9 / 2)printf("impossible\n");
        else printf("%d\n",s[x][y]);
    }
}

网上找的floyd判断是否有负环

for(int i = 1; i <=n ; i++)
		if(d[i][i] < 0) return true;
	return false; 

今日练习的挺少的,应该多抄抄模板,刚开始学前两个最短路还挺清晰,现在学多了全都记不太清是啥了

明日任务:多熟悉这两天学的求最短路问题的模板,给搜索与图论(3)开头

  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: acwing算法基础课是一门针对算法学习的在线课程,在这门课程中,学生可以系统地学习和掌握算法基础知识,提高编程水平。为了方便学生学习acwing提供了网盘服务。 acwing算法基础课网盘是一个用于存储课程资源的平台。通过这个网盘,学生可以下载课程讲义、代码模板以及补充材料等。这些资源都经过精心整理,供学生们参考和学习。 网盘中的资源是按照课程章节进行分类的,学生可以根据自己的学习需要,选择性地下载所需的资料。同时,网盘还提供了搜索功能,方便学生快速定位和获取所需资料。 acwing算法基础课网盘的使用对于学生们的学习非常有帮助。通过下载和学习这些资源,学生们可以更好地理解课程内容,加深对算法的理解。此外,学生们还可以通过研究代码模板,学习优秀的编程思想和技巧,提高自己的编程能力。 总之,acwing算法基础课网盘是一项非常便利和实用的服务,为学生们提供了更加全面和深入的学习资源,帮助他们更好地掌握和运用算法知识。 ### 回答2: acwing算法基础课是一门优质的算法学习资源,其中的课程内容丰富多样,涵盖了算法基础知识、数据结构、动态规划、图论等等。很多学习者都认为这门课程对他们的算法学习有很大的帮助。 网盘是指以网络为媒介,提供文件存储和下载服务的云存储平台。acwing算法基础课也提供了网盘服务,方便学习者下载课程资料并进行学习。 通过acwing算法基础课网盘,学习者可以方便地获取到课程的各种学习资料,包括讲义、习题集、代码示例等。这些资料可以帮助学习者更好地理解和掌握课程的内容。此外,网盘还提供了上传和分享功能,学习者可以将自己的学习心得、代码等资料分享给其他学习者,促进学习者之间的互相学习和交流。 acwing算法基础课网盘的优点不仅仅是方便快捷的下载和分享功能,还包括安全可靠的存储环境。学习者可以放心地将自己的学习资料上传到网盘进行备份,减少数据丢失的风险。同时,网盘还提供了多种存储空间容量的选择,满足学习者不同的需求。 总的来说,acwing算法基础课网盘为学习者提供了方便、安全和多样化的学习资源下载和分享服务,为学习者的算法学习和进步提供了有力的支持。如果你对算法感兴趣,我推荐你去尝试一下这门精彩的课程!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值