Floyd算法

弗洛伊德算法

基本思想

  • 先限制从u到v的路径只能经过1号结点或不经过1号结点
  • 再放宽限制,u到v的路径可以从2号结点或不经过2号结点
  • 以此类推,从u到v的路径可以经过任意中继结点或者不经过任意中继节点

特性

  • 可以处理负边

源码 HDU 1874

#include<iostream>
#include<queue>
#include<list>
#include<vector>
#include<cstring>
#include<set>
#include<stack>
#include<map>
#include<cmath>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
typedef long long ll;
#define MS(x,i) memset(x,i,sizeof(x))
#define rep(i,s,e) for(int i=s; i<=e; i++)
#define sc(a) scanf("%d",&a)
#define scl(a) scanf("%lld",&a)
#define sc2(a,b) scanf("%d %d", &a, &b)
#define debug printf("debug......\n");
#define pfd(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
const double eps=1e-8;
const double PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x7fffffff;
const int maxn = 2e2+10;
int dx[4] = {0, 0, 1, -1};
int dy[4]  = {1, -1, 0 , 0};

int dis[maxn][maxn];
int s,e;
int x,y,w;
int n,m;

//起点可以从0 改为 1
void Floyd(){
    rep(k,0,n)//中继点从0到n开始枚举
    rep(i,0,n)// 从i到j的距离更新 可以多经过中继点
    rep(j,0,n)
    if(dis[i][j] > dis[i][k] + dis[k][j]) 
    dis[i][j] = dis[i][k] + dis[k][j];
}

int main(){
    while(cin>>n>>m){
        rep(i,0,n){
            rep(j,0,n){
                if(i==j) dis[i][j] = 0;
                else dis[i][j] = inf;
            }
            
        }
        rep(i,1,m){
            cin>>x>>y>>w;
            if(dis[x][y] > w){
                dis[x][y] = w;
                dis[y][x] = w;
            }
            
        }

        Floyd();

        cin>>s>>e;
        if(dis[s][e] == inf) cout<<-1<<endl;
            else cout<<dis[s][e]<<endl;
        }
    return 0;
}

posted @ 2019-04-16 10:59  西风show码  阅读(176)  评论(0编辑  收藏  举报