最短路径模板

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

图存储方式:邻接矩阵(有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<<"路径:\n";
              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\n",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\n",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\n",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

 

posted @ 2018-11-21 16:58  shenyuli  阅读(245)  评论(0编辑  收藏  举报
Live2D