poj 3613 矩阵快速幂变形(恰好k条边最短路)

本文介绍了一种求解特定长度的最短路径问题的方法,利用邻接矩阵和快速幂技巧实现。通过不断加倍路径长度,最终得到给定点对间确切长度k的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给定一个无向图和一个点对(a,b),求从a到b的恰好长度为k的最短路。

思路:对于图的邻接矩阵,做一次add(见代码)操作,元素变成长度为2的最短路,再自身一次就是长度为4的最短路。按照这个思路加上快速幂的思路就OK了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstdlib>
using namespace std;
#define clc(s,t) memset(s,t,sizeof(s))
#define INF 0x3fffffff
#define N 205
struct edge{
    int x,y,w;
}e[105];
struct matrix{
    int a[N+5][N+5];
}g,res;
int k,m,x,y,s[N],len;
struct matrix add(matrix p,matrix q){
    struct matrix ans;
    int i,j,k;
    for(i = 1;i<=len;i++)
        for(j = 1;j<=len;j++){
            ans.a[i][j] = INF;
            for(k = 1;k<=len;k++)
                ans.a[i][j] = min(ans.a[i][j],p.a[i][k]+q.a[k][j]);
        }
    return ans;
}
void solve(int n){
    int f = 0;
    while(n){
        if(n&1){
            if(f==0){
                f = 1;
                res = g;
            }else
                res = add(res,g);
        }
        g = add(g,g);
        n>>=1;
    }
}
int main(){
    int i,j,a,b;
    scanf("%d %d %d %d",&k,&m,&x,&y);
    for(i = 0;i<m;i++){
        scanf("%d %d %d",&e[i].w,&e[i].x,&e[i].y);
        s[i*2] = e[i].x;
        s[i*2+1] = e[i].y;
    }
    sort(s,s+m*2);
    len = unique(s,s+m*2)-s;
    for(i = 1;i<=len;i++)
        for(j = 1;j<=len;j++)
            g.a[i][j] = res.a[i][j] = INF;
    for(i = 0;i<m;i++){
        a = lower_bound(s,s+len,e[i].x)-s+1;
        b = lower_bound(s,s+len,e[i].y)-s+1;
        g.a[a][b] = g.a[b][a] = e[i].w;
    }
    solve(k);
    x = lower_bound(s, s+len, x)-s+1;
    y = lower_bound(s, s+len, y)-s+1;
    printf("%d\n",res.a[x][y]);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值