【图论】最短路(二)

 3.亲爱的题题们

3.0 模板floyd

B3647 【模板】Floyd - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

数据水,不用判>INF/2

#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f
//用7fffffff或者多输几个9就溢出成负数
int main(){

    int n,e;
    cin>>n>>e;

    int E[101][101];



    for(int i=0;i<101;i++){
        for(int j=0;j<101;j++){
            E[i][j]=INF;
               E[i][i]=0;
        }
    }
for(int i=0;i<e;i++){
        int u,v,w;
cin>>u>>v>>w;
E[u][v]=min(E[u][v],w);
E[v][u]=E[u][v];
}

for(int k=1;k<=n;k++){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            E[i][j]=min(E[i][j],E[i][k]+E[k][j]);

        }
    }
}


for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
        if(j==1)cout<<E[i][j];
        else{
            cout<<" "<<E[i][j];
        }

    }
    if(i!=n)cout<<endl;
}

}

3.1 模板最短路x1

P3371 【模板】单源最短路径(弱化版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

2147483647是个好数字,是32_int表示的最大值,前面留一个符号位,2^31-1=(1<<31)-1

移位运算符怎么用,看下面的程序

这也看出define是编译时把代码文本替换了

#include<iostream>
#define INF1 1<<31-1
#define INF2 (1<<31)-1
#define INF3 ((1<<31)-1)
using namespace std;
int main(){

    cout<<INF1<< " "<<INF2<<" "<<INF3<<endl;

    long long x1=INF1,x2=INF2,x3=INF3;
    cout<<x1<<" "<<x2<< " " <<x3;
}

输出

130 2147483647 2147483647
1073741824 2147483647 2147483647

3.1 模板最短路x2

公交线路 (nowcoder.com)

单源

边权正数,dijkstra

10^5内,朴素即可搞定

#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f

int s,t,n,m;
long disic[1001];
long disii[1001][1001];
bool book[1001]={0};

void dijkstra(){
    disic[s]=0;
    book[s]=1;//if(!book[i])
    for(int i=1;i<=n;i++)if(!book[i])disic[i]=min(disic[i],disic[s]+disii[i][s]);
    
    for(int i=1;i<=n;i++){
        long temp=INF;
        int t0=-1;
        for(int i=2;i<=n;i++){
            if(!book[i]&&disic[i]<temp){
                temp=disic[i];
                t0=i;
            }
        }
        if(t0==-1)continue;//最后10%
        
        book[t0]=1;
        for(int i=1;i<=n;i++)if(!book[i])disic[i]=min(disic[i],disic[t0]+disii[i][t0]);
    }
    if(disic[t]==INF)cout<<-1;
    else cout<<disic[t];
}

int main(){
    cin>>n>>m>>s>>t;
    for(int i=1;i<=n;i++){
        disic[i]=INF;
        disii[i][i]=0;
         for(int j=1;j<i;j++){
             disii[i][j]=INF;
             disii[j][i]=INF;
         }                
    }
    for(int i=1;i<=m;i++){
        int u,v;long w;
        cin>>u>>v>>w;
        disii[u][v]=min(disii[u][v],w);
        disii[v][u]=disii[u][v];
    }
    dijkstra();
    
}

3.2 模板最短路x3

有坑

#include<iostream>
using namespace std;
#include<vector>
#include<queue>
#define ll long long
#define INF 0x3f3f3f3f

ll total=0;
ll n,m,k,s,t;
ll dist[1000001];
bool st[1000001]={0};
ll head[1000001];
struct EDGE{
ll next;
ll to;
ll w;
}edge[10000001];

void addedge(ll u,ll v,ll w){
edge[++total].next=head[u];
edge[total].to=v;
edge[total].w=w;
head[u]=total;

}

void dijkstra(){
priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>>heap;
heap.push({0,s});
dist[s]=0;

while(!heap.empty()){
    pair<ll,ll>temp=heap.top();
    heap.pop();

    ll x=temp.first,y=temp.second;
    if(st[y])continue;
    st[y]=true;

    for(ll i=head[y];i!=-1;i=edge[i].next){
        ll t0=edge[i].to;
        if(dist[t0]>x+edge[i].w){
            dist[t0]=x+edge[i].w;
            heap.push({dist[t0],t0});
        }
    }



}

ll ans=INF;
for(ll i=0;i<=k;i++)ans=min(ans,dist[t+i*n]);
if(ans==INF)cout<<-1;
else cout<<ans;
}




int main()
{
    cin>>n>>m>>k>>s>>t;

    for(ll i=0;i<=(k+1)*n;i++){head[i]=-1;dist[i]=INF;}
    for(ll i=1;i<=m;i++){
            ll u,v,w;cin>>u>>v>>w;
        addedge(u,v,w);
        addedge(v,u,w);
        for(int j=1;j<=k;j++){
                addedge(u+j*n,v+j*n,w);
                addedge(v+j*n,u+j*n,w);
            addedge(u+(j-1)*n,v+j*n,0);
            addedge(v+(j-1)*n,u+j*n,0);

        }
    }

    dijkstra();
}

3.3 差分约束

c_{u}<=c_{v}+w_{v->u}边反着建

建立源点0,到其他点均有一条权为0的有向边

由于是bellman-ford是对边操作,不会dis[]全为0

跟新:

为了防止不连通(可能有那么一个难找的点可以做源点,也可能根本没有)加入源点0

0要到别的点都有边,(全是正数只是赠品)

从0开始spfa

P5960 【模板】差分约束 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
int dist[5001];
struct EDGE{
int u;
int v;
int w;
}edge[10001];
void bellman(){
    bool ok;
for(int i=1;i<=n+1;i++){
    ok=1;

    for(int j=1;j<=m+n;j++){
            int u=edge[j].u;int v=edge[j].v;
//
        if(dist[u]!=INF&&dist[v]>dist[u]+edge[j].w){
            dist[v]=dist[u]+edge[j].w;
            if(ok==true)ok=false;
        }
    }

    if(ok==1)break;
}
if(ok!=1)cout<<"NO";
else {
    for(int i=1;i<=n;i++){if(i!=1)cout<<" ";cout<<dist[i];}
}


}


int main(){
    cin>>n>>m;
for(int i=1;i<=n;i++){
        dist[i]=INF;
edge[i+m].u=0;
edge[i+m].v=i;
edge[i+m].w=0;
}

for(int i=1;i<=m;i++){
    cin>>edge[i].v>>edge[i].u>>edge[i].w;

}
bellman();


}

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]提供了使用Python的networkx库绘制网络图和计算最短加权路径的示例代码。该代码使用了一个包含顶点和边的列表,并使用add_nodes_from和add_weighted_edges_from方法将它们添加到图中。然后,使用nx.shortest_path_length方法计算了从顶点v1到顶点v11的最短加权路径长度为13。\[1\] 引用\[2\]提供了一个计算最短路径的Python程序示例。该程序使用了numpy和networkx库。首先,定义了一个包含顶点和边的列表,并使用add_nodes_from和add_weighted_edges_from方法将它们添加到图中。然后,使用nx.shortest_path_length方法计算了最短路径长度,并将结果存储在一个字典中。接下来,使用numpy创建了一个6x6的零矩阵,并使用两个嵌套的for循环将最短路径长度填充到矩阵中。最后,使用矩阵乘法计算了运力,并找到了最小运力和对应的位置。\[2\] 引用\[3\]提供了关于Dijkstra算法的一些背景信息。Dijkstra算法是一种寻找最短路径的算法,适用于所有权重大于等于0的情况。它可以用于解决从一个起始点到任意一个点的最短路径问题。\[3\] 综上所述,如果你想在Python中计算图论中的最短路径,可以使用networkx库和Dijkstra算法。你可以根据引用\[1\]和引用\[2\]中的示例代码进行操作。 #### 引用[.reference_title] - *1* *3* [运筹学——图论与最短距离(Python实现)](https://blog.csdn.net/weixin_46039719/article/details/122521276)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [数学建模:图论模型 — 最短路模型示例 (Python 求解)](https://blog.csdn.net/qq_55851911/article/details/124776487)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值