单源最短路(bellman-ford算法+dijkstra算法)+任意两点最短路(floyd-warshall算法)

ps:本来是复习图论的,最后变成了预习,隔了一段时间简直了,重新学过!

哈哈哈哈哈哈哈,,真的菜啊!

   单源最短路问题是求,,固定一个起点,求它到其他所有点的最短路问题。

  两点之间最短路是求,固定起点和终点求最短路

两者没有根本区别,复杂度也是一样的

1,单源最短路1 bellman-ford算法

核心算法:

d[i]=min(d[j]+(从顶点j到顶点i边的权值),d[i])

d【i】表示任意点到顶点i的最短距离

一般初始化为INF,,然后起点d【s】初始化0。

只要图中不存在负圈(负圈是指两点间权值为负数所形成的圈)更新操作就是有限的

struct edge// 从顶点from——>to的权值为cost的边
{
    int from;   
    int to;
    int cost;
};
edge es[maxn];  //
int d[maxn];    //最短距离
int v,b;        //分别为顶点和边数
void bellman(int s)//从顶点开始递归
{
   for(int i=0;i<v;i++)
        d[i]=INF;//先把所有顶点的最短距离设为最大,排除自圈
   d[s]=0;//初始化起点
   while(true)
   {
       bool vis=false;
       for(int i=0;i<b;i++)
       {
           edge e=es[i];
           if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost)
           {
               d[e.to]=d[e.from]+e.cost;
               update=true;
           }
       }
       if(!update)break;
   }
   
}

算了找到了大佬的详细思路,我看懂了再来补把

bellman-ford算法:http://www.wutianqi.com/?p=1912

附上自己盲敲的代码,和大佬的一样

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#define maxn 1000
#define inf 100000
using namespace std;
struct node{
   int from,to,cost;
}edge[maxn];
int d[maxn];
int n,bian,changdu,s;//节点数,边数,边长,起点
void init()
{
    cin>>n>>bian>>s;
    for(int i=0;i<n;i++)
        d[i]=inf;
        d[s]=0;
   for(int i=0;i<bian;i++)
   {
       cin>>edge[i].from>>edge[i].to>>edge[i].cost;
       if(edge[i].from==s)
       {
           d[edge[i].to]==edge[i].cost;
       }
   }
}
void rex(int from,int to,int cost)
{
    if(d[to]>d[from]+cost)
    {
        d[to]=d[from]+cost;
    }
}
bool bellman()
{
    for(int i=0;i<n-1;i++)
        for(int j=0;j<bian;j++)
    {
        rex(edge[j].from,edge[j].to,edge[j].cost);
    }
    bool flag=1;
    for(int k=0;k<bian;k++)
    {
        if(d[edge[k].from]>d[edge[k].to]+edge[k].cost)
        {
            flag=0;
            break;
        }
    }
    return flag;
}
int main()
{
      init();
      if(bellman())
      {
          for(int i=0;i<=n;i++)
          {
              cout<<d[i]<<endl;
          }
      }
      return 0;
}

dijkstra算法:http://www.wutianqi.com/?p=1890

查错查了两个小时啊,我tm开心。

// 普通版迪杰斯特拉   o(n*n)

//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cmath>
//#include<queue>
//#include<set>
//#include<algorithm>
//#include<map>
//#define maxn 1000
//#define inf 100000
//using namespace std;
//int n,bian;
//int mp[maxn][maxn];
//int u,v,cost;
//int dis[maxn];
//int pre[maxn];
//void init()
//{
//    cin>>n>>bian;
//    //memset(mp,inf,sizeof(mp));
//    for(int i=1;i<=n;i++)
//    for(int j=1;j<=n;j++)
//    mp[i][j]=inf;
//    for(int i=0;i<bian;i++){
//        cin>>u>>v>>cost;
//        mp[u][v]=cost;
//        mp[v][u]=cost;
//    }
//    for(int i=1;i<=n;i++)
//    {
//        dis[i]=inf;
//    }
//}
//void dijkstra(int n,int v)
//{
//    bool vis[maxn];
//    for(int i=1;i<=n;i++)
//    {
//        vis[i]=false;
//        dis[i]=mp[v][i];
//        if(dis[i]==inf)
//        {
//            pre[i]=0;
//        }
//        else pre[i]=v;
//    }
//    dis[v]=0;
//    vis[v]=true;
//    for(int i=2;i<=n;i++)
//    {
//            int u=v;
//            int mazz=inf;
//            for(int j=1;j<=n;j++){
//        if(!vis[j]&&dis[j]<mazz)//换dis最小的顶点继续查找
//        {
//                u=j;
//                mazz=dis[j];
//        }
//        }
//        vis[u]=true;
//        for(int k=1;k<=n;k++)//更新顶点上的dis
//        {
//            if(!vis[k]&&mp[u][k]<inf)
//            {
//                if(dis[k]>mp[u][k]+dis[u]){
//                    dis[k]=mp[u][k]+dis[u];
//                    pre[k]=u;
//                }
//            }
//        }
//
//    }
//}
//void chazhaolujing(int *pre,int v,int n)
//{
//    int tot=1;
//    int que[maxn];
//    que[tot++]=n;
//    int tem=pre[n];
//    while(tem!=v)
//    {
//        que[tot]=tem;
//        tot++;
//        tem=pre[tem];
//    }
//    que[tot]=v;
//    for(int i=tot;i>=1;i--)
//    {
//        if(i!=1)cout<<que[i]<<"-->";
//        else cout<<que[i]<<endl;
//    }
//
//}
//int main()
//{
//     init();
//     dijkstra(n,1);
//     cout<<dis[n]<<endl;
//     chazhaolujing(pre,1,n);
//     return 0;
//}

//5
//7
//1 2 10
//1 4 30
//1 5 100
//2 3 50
//3 5 10
//4 3 20
//4 5 60
//输出数据:
//60
//1 -> 4 -> 3 -> 5


//优先队列优化版的迪杰斯特拉   0(n*logn)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#define maxn 1000
using namespace std;
const int inf=1e9+7;
vector<pair<int ,int> >e[maxn];//建立图
int dis[maxn];
void init()
{
    for(int i=0;i<maxn;i++)
        e[i].clear();
    for(int i=0;i<maxn;i++)
        dis[i]=inf;
}
int n,m;
void dijkstra(int s)
{
   priority_queue<pair<int,int> >q;
   dis[s]=0;
   q.push(make_pair(-dis[s],s));
   while(!q.empty())
   {
       int now=q.top().second;
       q.pop();
       for(int i=0;i<e[now].size();i++)
       {
           int v=e[now][i].first;//为了用起来方便而赋值
           if(dis[v]>dis[now]+e[now][i].second)//更新顶点的dis值
           {
               dis[v]=dis[now]+e[now][i].second;
               q.push(make_pair(-dis[v],v));
           }
       }
   }
}
int main()
{
    while(cin>>n>>m)
    {
        int i,j;
        init();
        for(i=0; i<m; i++)
        {
            int x,y,z;
            scanf("%d %d %d",&x,&y,&z);
            e[x].push_back(make_pair(y,z));//e[x].push_back(y);
            e[y].push_back(make_pair(x,z));
        }
        int s,t;
        scanf("%d %d",&s,&t);
        dijkstra(s);
         if(dis[t]==inf)cout<<"-1"<<endl;
       else cout<<dis[t]<<endl;
   }
  return 0;
}

//Sample Input
//3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
//
//
//Sample Output
//2 -1

 floyd算法:http://www.wutianqi.com/?p=1903

原文地址:https://www.cnblogs.com/huangzzz/p/8324814.html