• dijkstra算法模板_HDU3790


    问题描述:  有n个点,m个边,每条边上有一个权值,求从s节点到e节点的最短路径,即途径路上的权值和为最小。 

          是求单起点,多终点最短路的问题。

    dijkstra算法基本思想

    1:设置一个distanse数组,存储从起始点s到各个节点的距离(权值和),distanse[i]即从s到i的最短路

    2:初始状态,distanse[i]=mp[s][i],found[s]=1

    3:每次从所有 1未访问的节点中  挑出 2distanse最小的点k  choose() 进行松弛操作;

    4:松弛操作。如果经过k到j的distanse小于原来的distanse  更新distanse  

        if(dis[k]+mp[k][j]<dis[j])   dis[j]=dis[k]+mp[k][j];

    dijkstar 算法的时间复杂度是O(N^2)可以用对优化到O(N*LogN)级别

        用了贪心的思想,只能用于正权边,带负权的会导致贪心的bug

    本题是两个权,距离和cost,分优先级的进行dijkstra,比较水。

    不过还是要注意数组下标别写错了,错一个就是WA!

    dijkstra算法只有两个过程 1:选择下一个要操作的点    2:松弛

    对图的存储使用  邻接矩阵  和  链式前向星 (感觉和邻接表是一回事)都是一样的,只要稍微改一下代码

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 1005 , INF = 0x3f3f3f;
     5 int mp[maxn][maxn],dis[maxn],fond[maxn],cost[maxn][maxn],wei[maxn];
     6 int n,m,a,b,d,p,s,t;
     7 
     8 void input()
     9 {
    10     while(m--)
    11     {
    12         scanf("%d%d%d%d",&a,&b,&d,&p);
    13         if(mp[a][b]>d)
    14         {
    15             mp[a][b]=mp[b][a]=d;
    16             cost[a][b]=cost[b][a]=p;
    17         }
    18         else if(mp[a][b]==d)
    19         {
    20             cost[a][b]=cost[b][a]=min(cost[a][b],p);
    21         }
    22     }
    23     cin>>s>>t;
    24 }
    25 
    26 int choose()
    27 {
    28     int cnt = -1,minn=INF;
    29     for(int i=1;i<=n;i++)
    30     {
    31         if(!fond[i]&&minn>dis[i])
    32         {
    33             minn=dis[i];
    34             cnt=i;
    35         }
    36     }
    37     return cnt;
    38 }
    39 
    40 void dijkstra()
    41 {
    42     for(int i=1;i<=n;i++)
    43     {
    44         fond[i]=0;
    45         dis[i]=mp[s][i];
    46         wei[i]=cost[s][i];
    47     }
    48     fond[s]=1;
    49     for(int i=1;i<=n;i++)
    50     {
    51         int k=choose();
    52         if(k==-1)return ;
    53         fond[k]=1;
    54         for(int j=1;j<=n;j++)
    55         {
    56             if(!fond[j])
    57             {
    58                 if(dis[k]+mp[k][j]<dis[j]){
    59                     dis[j]=dis[k]+mp[k][j];
    60                     wei[j]=wei[k]+cost[k][j];
    61                 }
    62                 else if( dis[j]==dis[k]+mp[k][j])
    63                 {
    64                     wei[j]=min(wei[j],wei[k]+cost[k][j]);
    65                 }
    66             }
    67         }
    68     }
    69 }
    70 
    71 int main()
    72 {
    73     while(cin>>n>>m,n,m)
    74     {
    75         memset(mp,INF,sizeof(mp));
    76         memset(cost,INF,sizeof(cost));
    77         input();
    78         dijkstra();
    79         cout<<dis[t]<<" "<<wei[t]<<endl;
    80     }
    81     return 0;
    82 }
    View Code

     下面的HDU1874是经典模板题

     dis[t]=0一定要加上

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 205, INF = 10000000;
     5 int mp[maxn][maxn],found[maxn],dis[maxn];
     6 int n,m,s,t,a,b,x;
     7 void input()
     8 {
     9     //memset(mp,INF,sizeof(mp));
    10     for(int i=0;i<n;i++)
    11         for(int j=0;j<n;j++)
    12             mp[i][j]=INF;
    13     memset(found,0,sizeof(found));
    14     while(m--)
    15     {
    16         scanf("%d%d%d",&a,&b,&x);
    17         if(x<mp[a][b]) mp[a][b]=mp[b][a]=x;
    18     }
    19     cin>>s>>t;
    20 }
    21 
    22 int  choose()
    23 {
    24     int cnt=-1,minn=INF;
    25     for(int i=0;i<n;i++)
    26     {
    27         if(!found[i]&&dis[i]<minn)
    28         {
    29             cnt=i;minn=dis[i];
    30         }
    31     }
    32     return cnt;
    33 }
    34 
    35 void dijkstra()
    36 {
    37     for(int i=0;i<n;i++)
    38     {
    39         dis[i]=mp[s][i];
    40     }
    41     found[s]=1;
    42     dis[s]=0;
    43     for(int i=0;i<n;i++)
    44     {
    45         int k=choose();
    46         if(k==-1)return;
    47         found[k]=1;
    48         for(int j=0;j<n;j++)
    49         {
    50             if(!found[j]&&dis[k]+mp[k][j]<dis[j])
    51             {
    52                     dis[j]=dis[k]+mp[k][j];
    53             }
    54         }
    55     }
    56 }
    57 
    58 
    59 int main()
    60 {
    61     while(cin>>n>>m)
    62     {
    63         input();
    64         dijkstra();
    65         if(dis[t]==INF)cout<<"-1"<<endl;
    66         else cout<<dis[t]<<endl;
    67 
    68     }
    69     return 0;
    70 }
    View Code
    落霞与孤鹜齐飞,秋水共长天一色
  • 相关阅读:
    webstorm快捷键大全
    Js的reduce()方法
    利用 c# linq 实现多个数据库的联合查询
    微信小程序支付接入注意点
    ubuntu所有php扩展php-7.0扩展列表
    ubuntu 16.04 php 安装curl方法
    Ubuntu下配置Apache开启HTTPS
    Mac下如何用SSH连接远程Linux服务器及Linux一些常用操作命令,更新中.....
    Mac下如何用SSH连接远程Linux服务器
    C#的dapper使用
  • 原文地址:https://www.cnblogs.com/star-and-me/p/6663457.html
Copyright © 2020-2023  润新知