zoukankan      html  css  js  c++  java
  • poj 3613 floyd + 快速幂

    题意:本题的大意就是问从S 到 T 经过边得个数恰为k的最短路是多少。

    思路:对于邻接矩阵每一次floyd求的是每个点间的最短距离,则n次floyd就是每个点间n条路的最短距离(可以重复边);

    但是由于k次floyd时间复杂度会超,则运用了快速幂的方法。

    代码:

    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #define MAXN 1005
    #define MAXM 500005
    #define INF 1000000000
    using namespace std;
    int k, m, s, t;
    int ans[MAXN][MAXN], mp[MAXN][MAXN], tmp[MAXN][MAXN], dis[MAXN][MAXN];
    int used[MAXN], v[MAXN], num;
    void floyd(int c[][MAXN], int a[][MAXN], int b[][MAXN])
    {
        for(int k = 0; k < num; k++)
            for(int i = 0; i < num; i++)
                for(int j = 0; j < num; j++)
                    if(c[v[i]][v[j]] > a[v[i]][v[k]] + b[v[k]][v[j]])
                        c[v[i]][v[j]] = a[v[i]][v[k]] + b[v[k]][v[j]];
    }
    void copy(int a[][MAXN], int b[][MAXN])
    {
        for(int i = 0; i < num; i++)
            for(int j = 0; j < num; j++)
            {
                a[v[i]][v[j]] = b[v[i]][v[j]];
                b[v[i]][v[j]] = INF;
            }
    }
    void slove(int k)
    {
        while(k)
        {
            if(k & 1)
            {
                floyd(dis, ans, mp);
                copy(ans, dis);
            }
            floyd(tmp, mp, mp);
            copy(mp, tmp);
            k >>= 1;
        }
    }
    int main()
    {
        int x, y, w;
        scanf("%d%d%d%d", &k, &m, &s, &t);
        for(int i = 0; i <= 1000; i++)
        {
            for(int j = 0; j <= 1000; j++)
            {
                mp[i][j] = INF;
                tmp[i][j] = INF;
                dis[i][j] = INF;
                ans[i][j] = INF;
            }
            ans[i][i] = 0;
        }
        num = 0;
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d", &w, &x, &y);
            if(!used[x])
            {
                used[x] = 1;
                v[num++] = x;
            }
            if(!used[y])
            {
                used[y] = 1;
                v[num++] = y;
            }
            if(mp[x][y] > w)
                mp[x][y] = mp[y][x] = w;
        }
        slove(k);
        printf("%d
    ", ans[s][t]);
        return 0;
    }


     

  • 相关阅读:
    oracle python操作 增删改查
    python连接oracle
    opengl问题
    [转]C++ 获取文件夹下的所有文件名
    @RequestMapping[转]
    hdu 6082
    maven/ssm框架搭建
    windows下mysql解压版安装及centos下mysql root密码忘记
    maven创建web项目
    eclipse用tomcat发布网站的目录
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134132.html
Copyright © 2011-2022 走看看