zoukankan      html  css  js  c++  java
  • Floyd算法——计算图中任意两点之间的最短路径

    百度百科定义:传送门

    一、floyd算法

    说实话这个算法是用来求多源最短路径的算法。

    算法原理:

    1,从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
    2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。
    把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i][j]=d,d表示该路的长度;否则G[i][j]=无穷大。定义一个矩阵D用来记录所插入点的信息,D[i][j]表示从Vi到Vj需要经过的点,初始化D[i][j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i][j] = min( G[i][j], G[i][k]+G[k][j] ),如果G[i][j]的值变小,则D[i][j]=k。在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。
    typedef long long int lli;
    lli map[5001][5001];
    int n;
    
    void floyd()
    {
        for (register int i=1;i<=n;i++)
            for (register int j=1;j<=n;j++)
                for (register int k=1;k<=n;k++)
                    if (map[i][j]>map[i][k]+map[k][j])
                        map[i][j]=map[i][k]+map[k][j];
    }

    最后程序中的map[i][j]就是i->j的最短路径长度。

    时间复杂度:O(n3),空间复杂度:S(n2)(用的是邻接矩阵)。

    所以一般要用这种算法的题数据范围都会很小(1000的三次方就十亿了,你说呢)

    洛谷P1744 采购特价

    显然是floyd的板子题

    光从n<=100的数据范围就能看出来......

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<time.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef pair<int,int> pr;
    const double pi=acos(-1);
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define Rep(i,u) for(int i=head[u];i;i=Next[i])
    #define clr(a) memset(a,0,sizeof a)
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define sc second
    ld eps=1e-9;
    ll pp=1000000007;
    ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
    ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
    ll read(){
        ll ans=0;
        char last=' ',ch=getchar();
        while(ch<'0' || ch>'9')last=ch,ch=getchar();
        while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
        if(last=='-')ans=-ans;
        return ans;
    }//head
    
    int n,m,s,t;
    double a[105][5],dis[105][105];
    
    int main()
    {
        n=read();
        rep(i,1,n)
            a[i][1]=read(),a[i][2]=read();
        memset(dis,0x7f,sizeof(dis));
        int x,y;
        m=read();
        rep(i,1,m)
        {
            x=read(),y=read();
            dis[y][x]=dis[x][y]=sqrt(pow(a[x][1]-a[y][1],2)+pow(a[x][2]-a[y][2],2));
        }
        s=read(),t=read();
        rep(k,1,n)
            rep(i,1,n)
                rep(j,1,n)
                {
                    if((i!=j&&i!=k&&j!=k&&dis[i][j]>dis[i][k]+dis[k][j])
                    dis[i][j]=dis[i][k]+dis[k][j];
                }
        printf("%.2lf",dis[s][t]);
        return 0;
    }
  • 相关阅读:
    MFC Windows 程序设计>WinMain 简单Windows程序 命令行编译
    AT3949 [AGC022D] Shopping 题解
    CF643D Bearish Fanpages 题解
    CF643C Levels and Regions 题解
    CF241E Flights 题解
    CF671C Ultimate Weirdness of an Array 题解
    CF1592F Alice and Recoloring 题解
    GYM 102452E 题解
    CF494C Helping People 题解
    P5556 圣剑护符
  • 原文地址:https://www.cnblogs.com/lcezych/p/10739885.html
Copyright © 2011-2022 走看看