• 最短路径模板


    适应对象:有权图(有向或无向都行)

    图存储方式:邻接矩阵(有0和INF的那种,否则就over)

    一、Floyd算法:

       1。核心代码:

        void floyd()
            {
                int i,j,k;
                for(i=0;i<g.n;i++)
                    for(j=0;j<g.n;j++)
                    {
                        dist[i][j]=g.edges[i][j];
                        if(i!=j&&g.edges[i][j]<inf)
                           path[i][j]=i;//有路 
                        else
                           path[i][j]=-1;//
                    }
                for(k=0;k<g.n;k++)
                   for(i=0;i<g.n;i++)
                    for(j=0;j<g.n;j++)
                      if(dist[i][j]>dist[i][k]+dist[k][j])
                      {
                        dist[i][j]=dist[i][k]+dist[k][j];
                        path[i][j]=path[k][j];
                      }
            }
    View Code

       2.完整代码(题目地址:http://tk.hustoj.com/problem.php?id=1120)

    #include<iostream>
    using namespace std;
    const int maxn=10;
    const int inf=32767;
    class Graph
    {
        struct matgraph
        {
            int n;
            int edges[maxn][maxn];
        };
        matgraph g;
        int dist[maxn][maxn];//存路径长度,比如dist[1][2]就是1->2的最短路径 
        int path[maxn][maxn];//具体路径 
        public :
            void make_matgraph(int n)
            {
                
                int m;
                g.n=n;
                cin>>m;
                for(int i=0;i<g.n;i++)
                    for(int j=0;j<g.n;j++)
                        if(i==j)
                           g.edges[i][j]=0;
                        else
                           g.edges[i][j]=inf;
                for(int i=0;i<m;i++)
                {
                    int a,b,c;
                    cin>>a>>b>>c;
                    g.edges[a-1][b-1]=c;
                    g.edges[b-1][a-1]=c;
                }
            }
            void floyd()
            {
                int i,j,k;
                for(i=0;i<g.n;i++)
                    for(j=0;j<g.n;j++)
                    {
                        dist[i][j]=g.edges[i][j];
                        if(i!=j&&g.edges[i][j]<inf)
                           path[i][j]=i;//有路 
                        else
                           path[i][j]=-1;//
                    }
                for(k=0;k<g.n;k++)
                   for(i=0;i<g.n;i++)
                    for(j=0;j<g.n;j++)
                      if(dist[i][j]>dist[i][k]+dist[k][j])
                      {
                        dist[i][j]=dist[i][k]+dist[k][j];
                        path[i][j]=path[k][j];
                      }
            }
            void ask()
            {
                int a,b;
                cin>>a>>b;
                a--;
                b--;
                if(dist[a][b]!=inf)
                { 
                  cout<<dist[a][b]<<endl;
                 /* cout<<"路径:
    ";
                  do
                  {
                      cout<<b+1<<" ";
                      b=path[a][b];
                  }while(b!=-1);*/
               }
                else
                  cout<<"No path"<<endl;
            }
    };
    int main()
    {
        Graph g;
        int n;
        while(cin>>n)
        {
        g.make_matgraph(n);
        g.floyd();
        g.ask();
        }
        return 0;
    }
    View Code

    二、Dijkstra算法

      1.邻接表实现

       a.核心代码:

    void dijkstra(const adjgraph g,int s,int t)
    {
        double dist[maxn]={0};
        int visited[maxn]={0};//标记是否拜访 
        int path[maxn];
        for(int i=1;i<=g.n;i++)
        {
            dist[i]=(double)inf;
            path[i]=-1;
        }
        visited[s]++;
        dist[s]=0;
        arcnode *p=g.adjlist[s].firstarc;
        while(p!=NULL)
        {
            dist[p->adjvex]=p->weight;
            path[p->adjvex]=s;
            p=p->nextarc;
        }
        for(int i=1;i<g.n;i++)
        {
            double minn=(double)inf;
            int u;
            for(int j=1;j<=g.n;j++)
                if(!visited[j]&&dist[j]<minn)//对未拜访的点进行比较 
                {
                    minn=dist[j];
                    u=j;
                }
            visited[u]++;
            arcnode *p=g.adjlist[u].firstarc;
            while(p!=NULL)//用新的点去更新路径 
            {
                if(!visited[p->adjvex]&& p->weight+minn<dist[p->adjvex])//lowcost 表示未拜访 
                {
                    dist[p->adjvex]=p->weight+minn;
                    path[p->adjvex]=u; 
                }
                p=p->nextarc;
            }
        }
        printf("%0.2lf
    ",dist[t]);
    }
    View Code

       b.完整代码:(题目地址:http://120.77.243.165/problem.php?id=3974)

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn=100;
    const int inf=32767;
    struct arcnode
        {
            int adjvex;
            double weight;
            arcnode *nextarc;
        };
    struct vnode
    {
            arcnode *firstarc;
    };
    struct adjgraph
    {
        int n;
        vnode adjlist[maxn];
    };
    struct vertex
    {
        int x;
        int y;
    };
    double get_weight(vertex a,vertex b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    void make_adjgraph(adjgraph &g)
    {
        int m;
        vertex dist[maxn];//存储坐标 
        cin>>g.n;
        for(int i=1;i<=g.n;i++)//Initial
            g.adjlist[i].firstarc=NULL;
        for(int i=1;i<=g.n;i++)
           cin>>dist[i].x >>dist[i].y;
        cin>>m;
        for(int i=0;i<m;i++)
        {
            int a,b;
            cin>>a>>b;
            double weight=get_weight(dist[a],dist[b]);
            arcnode *p=new arcnode;
            p->adjvex=b;
            p->weight=weight;
            p->nextarc=g.adjlist[a].firstarc;
            g.adjlist[a].firstarc=p;
            
            p=new arcnode;
            p->adjvex=a;
            p->weight=weight;
            p->nextarc=g.adjlist[b].firstarc;
            g.adjlist[b].firstarc=p;
        }
    }
    void dijkstra(const adjgraph g,int s,int t)
    {
        double dist[maxn]={0};
        int visited[maxn]={0};//标记是否拜访 
        int path[maxn];
        for(int i=1;i<=g.n;i++)
        {
            dist[i]=(double)inf;
            path[i]=-1;
        }
        visited[s]++;
        dist[s]=0;
        arcnode *p=g.adjlist[s].firstarc;
        while(p!=NULL)
        {
            dist[p->adjvex]=p->weight;
            path[p->adjvex]=s;
            p=p->nextarc;
        }
        for(int i=1;i<g.n;i++)
        {
            double minn=(double)inf;
            int u;
            for(int j=1;j<=g.n;j++)
                if(!visited[j]&&dist[j]<minn)//对未拜访的点进行比较 
                {
                    minn=dist[j];
                    u=j;
                }
            visited[u]++;
            arcnode *p=g.adjlist[u].firstarc;
            while(p!=NULL)//用新的点去更新路径 
            {
                if(!visited[p->adjvex]&& p->weight+minn<dist[p->adjvex])//lowcost 表示未拜访 
                {
                    dist[p->adjvex]=p->weight+minn;
                    path[p->adjvex]=u; 
                }
                p=p->nextarc;
            }
        }
        printf("%0.2lf
    ",dist[t]);
    } 
    int main()
    {
        adjgraph g;
        make_adjgraph(g);
        int s ,t;
        cin>>s>>t;
        dijkstra(g,s,t);
        return 0;
    }
    View Code

       2.邻接矩阵实现

       a.核心代码:

    void dijkstra(int v)
            {
                int visit[maxn]={0};//记录是否拜访
                for(int i=1;i<=g.n;i++)
                {
                    dist[i]=g.edges[v][i];
                    if(dist[i]!=inf&&i!=v)
                       path[i]=v;
                    else
                       path[i]=-1;
                }
                visit[v]++;
                for(int i=1;i<g.n-1;i++)
                {
                    double minn=inf;
                    int u;
                    for(int j=1;j<=g.n;j++)
                        if(!visit[j]&&dist[j]<minn)
                        {
                            u=j;
                            minn=dist[j];
                        }
                    visit[u]++;
                    for(int j=1;j<=g.n;j++)
                    {
                        if(!visit[j]&&minn+g.edges[u][j]<dist[j])
                        {
                            dist[j]=minn+g.edges[u][j];
                            path[j]=u;
                        }
                    }
                }
            }
    View Code

       b.完整代码:(题目地址:http://120.77.243.165/problem.php?id=3974)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn=100;
    const double inf=32767;
    class Graph
    {
        struct matgraph
        {
            int n;
            double edges[maxn][maxn];
        };
        struct vertex
        {
            int x;
            int y;
        };
        vertex coord[maxn];
        matgraph g;
        double dist[maxn];
        int path[maxn];
        public:
            double get_weight(int a,int b)
            {
                return sqrt((coord[a].x-coord[b].x)*(coord[a].x-coord[b].x)+(coord[a].y-coord[b].y)*(coord[a].y-coord[b].y));
            } 
            void make_matgraph()
            {
                cin>>g.n;
                for(int i=1;i<=g.n;i++)
                    for(int j=1;j<=g.n;j++)
                        if(i==j)
                           g.edges[i][j]=0;
                        else
                           g.edges[i][j]=inf;
                for(int i=1;i<=g.n;i++)
                    cin>>coord[i].x>>coord[i].y;
                int m;
                cin>>m;
                for(int i=0;i<m;i++)
                {
                    int a,b;
                    cin>>a>>b;
                    double weight=get_weight(a,b);
                    g.edges[a][b]=weight;
                    g.edges[b][a]=weight;
                 }    
            }
            void dijkstra(int v)
            {
                int visit[maxn]={0};//记录是否拜访
                for(int i=1;i<=g.n;i++)
                {
                    dist[i]=g.edges[v][i];
                    if(dist[i]!=inf&&i!=v)
                       path[i]=v;
                    else
                       path[i]=-1;
                }
                visit[v]++;
                for(int i=1;i<g.n-1;i++)
                {
                    double minn=inf;
                    int u;
                    for(int j=1;j<=g.n;j++)
                        if(!visit[j]&&dist[j]<minn)
                        {
                            u=j;
                            minn=dist[j];
                        }
                    visit[u]++;
                    for(int j=1;j<=g.n;j++)
                    {
                        if(!visit[j]&&minn+g.edges[u][j]<dist[j])
                        {
                            dist[j]=minn+g.edges[u][j];
                            path[j]=u;
                        }
                    }
                }
            }
            void ask_distance(int t)
            {
                printf("%0.2lf
    ",dist[t]);
                /*cout<<"路径:"<<t<<" ";
                while(path[t]!=-1)
                {
                   cout<<path[t]<<" ";
                   t=path[t];
                }
                cout<<endl;*/
            }
    };
    int main()
    {
        Graph a;
        a.make_matgraph();
        int s,t;
        cin>>s>>t;
        a.dijkstra(s);
        a.ask_distance(t); 
        return 0;
    }
    View Code
  • 相关阅读:
    程序员学习参考网站
    博客
    window对象
    事件触发顺序
    element对象
    正则表达式
    Date对象
    Number对象
    Math对象
    Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/shenyuling/p/9996159.html
Copyright © 2020-2023  润新知