Floyd算法——計算圖中任意兩點之間的最短路徑

百度百科定義:傳送門ios

1、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的最短路徑長度。spa

時間複雜度:O(n3),空間複雜度:S(n2)(用的是鄰接矩陣)。code

因此通常要用這種算法的題數據範圍都會很小(1000的三次方就十億了,你說呢)xml

洛谷P1744 採購特價blog

顯然是floyd的板子題ip

光從n<=100的數據範圍就能看出來......get

代碼:string

#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;
}
相關文章
相關標籤/搜索