经过N条边的最短路

http://acm.pku.edu.cn/JudgeOnline/problem?id=3613

求经过N条边的最短路 (2 ≤ N ≤ 1,000,000)

倍增floyd,主体是矩阵乘法。考虑一个x边的路径矩阵和y边的路径矩阵,两个矩阵用类似floyd的方法结合起来,就得到x+y边的路径矩阵,现在想要得到N边路径矩阵

然后就是“快速幂”的思想啦...把N拆成2的幂,只需要log(N)次矩阵乘法就搞定

伪floyd O(N^3),所以总的时间复杂度O(logN*n^3) 其中n是点的个数 由于最多100个边,所以n最大200

虽说只有最多200个点,然而点点序号却很迷的到了1000,所以用了离散化,把点的序号映射到1~200范围

答案矩阵开始时候应该为单位矩阵 在这个倍增floyd定义下 单位矩阵应该是迹为0 其他值为正无穷

#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int maxn = 207, INF = 0x3f3f3f3f;
map<int, int>M;
int cnt, n, t, s, e;
struct floyd{
    int a[maxn][maxn];
    floyd(){
        memset(a, INF, sizeof(a));
    }
    floyd operator * (const floyd& b){
        floyd c;
        for(int i = 1; i <= cnt; i++)
            for(int j = 1; j <= cnt; j++)
                for(int k = 1; k <= cnt; k++)
                    if(c.a[i][j] > a[i][k] + b.a[k][j])
                        c.a[i][j] = a[i][k] + b.a[k][j];
        return c;
    }
}st, ans;
void quick(){
   // ans = st;
   // n--;
    while(n){
        if(n&1){
            ans = ans*st;
        }
        st = st * st;
        n >>= 1;
    }
}
int main(){
    scanf("%d%d%d%d", &n, &t, &s, &e);
    cnt = 0;
    while(t--){
        int w, x, y;
        scanf("%d%d%d", &w, &x, &y);
        if(M[x])
            x = M[x];
        else
            x = M[x] = ++cnt;
        if(M[y])
            y = M[y];
        else
            y = M[y] = ++cnt;
        st.a[x][y] = st.a[y][x] = w;
    }
    for(int i = 1; i <= cnt; i++)
        ans.a[i][i] = 0;
    quick();
    printf("%d", ans.a[M[s]][M[e]]);
    return 0;
}
时间: 2024-10-19 10:25:57

经过N条边的最短路的相关文章

PKU 3613 Cow Relays (指定路径条数的最短路)

题意:N,T,S,E:给你T条边,每条边两端都有编号和权值,问从S走到E允许走N条边,求最短路. foyld加矩阵快速幂思想. 注意要把边离散 #include <iostream> #include <fstream> #include <string.h> #include <algorithm> using namespace std; #define M 303 #define inf 0x3fffffff struct node { int a[M

HDOJ 题目4396 More lumber is required(至少经过k条边的最短路)

More lumber is required Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Submission(s): 1392    Accepted Submission(s): 538 Problem Description "More lumber is required" When the famous warcrafts playe

hdu 1688 Sightseeing【最短路,次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题意:求最短路和次短路条数如果次短路长度=最短路长度+1 这输出次短路条数+最短路条数,否则输出最短路条数 分析:这是到模版题,献上模版: #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> #include<

POJ_3463_Sightseeing(最短路/次短路条数)

Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7421   Accepted: 2659 Description Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the bus moves from one city S to another city F. O

poj 3613 经过k条边最短路 floyd+矩阵快速幂

http://poj.org/problem?id=3613 s->t上经过k条边的最短路 先把1000范围的点离散化到200中,然后使用最短路可以使用floyd,由于求的是经过k条路的最短路,跑k-1次"floyd"即可(使用矩阵快速幂的思想). 把给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就

HDU 1688 Sightseeing 【输出最短路+次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题目大意:给n个点,m条有向边.再给出起点s, 终点t.求出s到t的最短路条数+次短路条数. 思路: 1.最短路和次短路是紧密相连的,在最短路松弛操作中,当我们找到一条更短的路径,也就意味着之前的路径不再是最短路,而成为了次短路,利用这个关系可以实现状态的转移. 2.好久没写优先队列了,都忘记了加个 priority_queue, 这样才能写重载,才能排序. 注释在代码里: 1 #includ

luogu P1144 最短路计数

题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M,为图的顶点数与边数. 接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边. 输出格式: 输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可.如果无法到达顶点i则输出0. 输入输出样例 输入样例#1

hdu1688(dijkstra求最短路和次短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题意:第k短路,这里要求的是第1短路(即最短路),第2短路(即次短路),以及路径条数,最后如果最短路和次短路长度差1,则输出两种路径条数之和,否则只输出最短路条数. 思路:dijkstra变形,注意状态的转移,代码上附了注释,就不多说了.. 代码: 1 #include <bits/stdc++.h> 2 #define MAXN 1010 3 using namespace std; 4

(寒假集训)Roadblock(最短路)

Roadblock 时间限制: 1 Sec  内存限制: 64 MB提交: 9  解决: 5[提交][状态][讨论版] 题目描述 Every morning, FJ wakes up and walks across the farm from his house to the barn.  The farm is a collection of N fields (1 <= N <= 250) connected by M bidirectional pathways (1 <= M