最短路....

这周把寒假没学的最短路看y总的课基本上学了学,然后今天全都自己手打一遍,记录一下我打的时候易错点。

朴素版的Dijkstra:

这个感觉还是好理解的,就是在更新t的时候条件,有直接一行写的但是要背,我背不出就靠理解写两个if然后里面条件不能忘特别是我写的第二个if的st[t]!=0;然后就是判断dist[n]是否存在是要大于等于0x3f3f3f3f。

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
typedef long long ll;
using namespace std;
const int N=505;
ll n,m;
ll bian[N][N];
ll dist[N];
bool st[N];
ll dijst(){
    memset(dist,0x3f3f3f3f,sizeof dist);
    dist[1]=0;
    ll t=1;
    for(int i=0;i<n;i++){
        for(int j=1;j<=n;j++){
            dist[j]=min(dist[j],dist[t]+bian[t][j]);
        }
        st[t]=1;
        t=-1;
        for(int j=1;j<=n;j++){
            if(t==-1&&st[j]==0) t=j;
            else if(t!=-1&&dist[j]<dist[t]&&st[j]==0)t=j;
        }
    }
    if(dist[n]>=0x3f3f3f3f)return -1;
    return dist[n];
}
int main(){
    memset(bian,0x3f3f3f3f,sizeof bian);
    cin>>n>>m;
    while(m--){
        ll a,b,c;
        cin>>a>>b>>c;
        bian[a][b]=min(bian[a][b],c);
    }
    ll ans=dijst();
    cout<<ans;
}

堆优化版的Dijkstra:

折磨一天才看懂的堆优化板子,主要点在优先队列和邻接表对我来说是新东西。然后这几天每天写一遍堆优化,每天都有错的地方。注意点就是优先队列对于pair是按first排序,然后就是不存在时的范围。最主要的还是邻接表的建立。

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
typedef long long ll;
using namespace std;
const int N=1e6+10;
typedef pair<ll,ll>PII;
ll n,m;
ll ed[N],ne[N],w[N],h[N],idx;
bool st[N];
ll dist[N];
void add(ll a,ll b,ll c){
    ed[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx;idx++;
}
ll dijst(){
    memset(dist,0x3f3f3f3f,sizeof dist);
    dist[1]=0;
    priority_queue<PII,vector<PII>,greater<PII>>heap;
    heap.push({0,1});
    while(heap.size()){
        auto t=heap.top();
        heap.pop();
        ll dian=t.second,juli=t.first;
        if(st[dian]==1)continue;
        st[dian]=1;
        for(int i=h[dian];i!=-1;i=ne[i]){
            ll j=ed[i];
            if(dist[j]>dist[dian]+w[i]){
                dist[j]=dist[dian]+w[i];
                heap.push({dist[j],j});
            }
        }
    }
    if(dist[n]>=0x3f3f3f3f) return -1 ;
    return dist[n];

}
int main(){
    memset(h,-1,sizeof h);
    cin>>n>>m;
    while(m--){
        ll a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
    }
    ll ans=dijst();
    cout<<ans<<endl;
}

bellman_ford:

这个就是结构体然后暴力更新,理解起来比较简单,可以处理存在负环边的情况,主要难点就在于dist的备份因为不能,在有边的次数限制下,本次更新可能会影响后面的更新,然后就要备份一下。

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
typedef long long ll;
using namespace std;
const int N=1e5+10;
ll n,m,k;
struct hh{
    ll a,b,c;
};
hh a[N];
ll dist[N];
ll last[N];
ll bemfd(){
    memset(dist,0x3f3f3f3f,sizeof dist);
    dist[1]=0;
    for(int j=0;j<k;j++){
        memcpy(last,dist,sizeof dist);
        for(int i=1;i<=m;i++){
            dist[a[i].b]=min(dist[a[i].b],last[a[i].a]+a[i].c);
        }
    }
    return dist[n];
}
int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++){
        ll x,y,z;
        cin>>x>>y>>z;
        a[i].a=x;
        a[i].b=y;
        a[i].c=z;
    }
    ll ans=bemfd();
    if(ans>=1e15) cout<<"impossible";
    else cout<<ans<<endl;
}

spfa:

这个时上一个的优化,用队列和邻接表实现,只有在距离改变的时候才加入队列然后之后在更新之后的路。感觉重点还是在邻接表。

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
typedef long long ll;
using namespace std;
const int N=1e5+10;
ll n,m;
ll ed[N],ne[N],w[N],h[N],idx;
ll dist[N];
bool st[N];
void add(ll a,ll b,ll c){
    ed[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx;idx++;
}
ll spfa(){
    memset(dist,0x3f3f3f3f,sizeof dist);
    dist[1]=0;
    queue<ll>q;
    q.push(1);
    while(q.size()){
        ll t=q.front();
        st[t]=0;
        q.pop();
        for(int i=h[t];i!=-1;i=ne[i]){
            ll j=ed[i];
            if(dist[j]>dist[t]+w[i]){
                if(st[j]==0){
                    q.push(j);
                    st[j]=1;
                }
                dist[j]=dist[t]+w[i];
            }
        }
    }
    return dist[n];
}
int main(){
    memset(h,-1,sizeof h);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        ll a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
    }
    ll ans=spfa();
    if(ans>=1e15) cout<<"impossible";
    else cout<<ans<<endl;
}

 四种方法的总结,啥时候用。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: darkbzoj.cc是一个在线的题库和程序设计平台。与其他常见的程序设计平台不同的是,darkbzoj.cc的难度较高,所以它更适合经验更为丰富的用户。平台集成了各种不同难度的编程挑战题目,包括算法、数学、图形、字符串、数据结构等领域,满足不同技能层级的编程爱好者需求。 在darkbzoj.cc的题库中,有许多有趣的题目,涵盖了各种算法和数据结构,如并查集、线段树、动态规划等。此外,该平台还可以服务于程序设计比赛,推广和发展技能水平。 因此,darkbzoj.cc不仅是一个有趣的编程平台,而且也是学习和提高编程技能的理想场所,值得更多编程爱好者的尝试和探索。 ### 回答2: darkbzoj.cc是一个在线编程题库,也可以称为黑暗集训队题库。这个网站的题目大部分都是计算机竞赛的经典题目,难度较高,主要面向ACM/ICPC竞赛选手、OI/NOI选手、算法研究人员以及对算法挑战感兴趣的程序员们。 这个网站包含了很多题目,其中很多都是经典的算法题目,如最短路、最小生成树、网络流、计算几何、字符串算法等。对于那些对这些经典算法感兴趣的人来说,这个网站是一个很好的学习资源。 除此之外,这个网站还提供了一些更加高级的算法题目,需要一些高级的知识来解决。因此,对于对于那些挑战自己的人来说,这个网站也是一个很好的选择。 总之,darkbzoj.cc提供了一个充满挑战的编程题库,为计算机科学专业的学生们以及程序员们提供了一个测试和提高他们编程技能的地方。 ### 回答3: Darkbzoj.cc是一个在线的算法竞赛平台,旨在为全球的程序员提供优秀的学习资源和挑战比赛。通过Darkbzoj.cc,用户可以学习算法、优化程序、提高编程技巧,并在比赛中体验竞技的乐趣。 Darkbzoj.cc提供了丰富的学习资料和编程题目,包括数据结构、算法基础、动态规划、图论以及数论等方面的知识。该平台具有良好的用户体验,界面清晰简洁,让用户更加专注于学习和编程。 此外,Darkbzoj.cc还提供了许多高质量的比赛,并与全球知名的算法竞赛平台进行合作,包括Codeforces、Atcoder、Topcoder等。这些比赛不仅能够提供良好的竞赛体验,还能够激励用户学习和提高自己的编程技能。 总之,Darkbzoj.cc是一个优秀的算法竞赛平台,不仅提供了优质的学习资源和编程题目,还能够为用户提供竞赛切磋的机会,是全球程序员必备的学习和竞赛平台。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值