POJ3613 k边最短路
Posted Narh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3613 k边最短路相关的知识,希望对你有一定的参考价值。
题目:http://poj.org/problem?id=3613
Floyd求最短路的实质是矩阵的自乘。( i , k )是第 i 行第k列,( k , j )是第k行第 j 列;用它们的max更新( i , j ),正是矩阵的自乘。
给一个矩阵赋予“已走 r 条边”的意义,则已走m条边的矩阵×已走n条边的矩阵得到的是已走m+n条边的矩阵。
用快速幂一样的方法加速,就行了。
重载运算符有待练习。
注意要先ans=a,n - -,原因见注释。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int N=205; int n,m,s,t,map[1005],cnt; struct Jz{ ll c[N][N]; Jz operator * (const Jz &a) const { Jz tmp; memset(tmp.c,1,sizeof tmp.c); for(int k=1;k<=cnt;k++) for(int i=1;i<=cnt;i++) for(int j=1;j<=cnt;j++) tmp.c[i][j]=min(tmp.c[i][j],c[i][k]+a.c[k][j]); // printf("k=%d i=%d j=%d c=%lld\n",k,i,j,c[i][k]);// return tmp; } }ans,a; int main() { memset(a.c,1,sizeof a.c); scanf("%d%d%d%d",&n,&m,&s,&t); int x,y;ll z; for(int i=1;i<=m;i++) { scanf("%lld%d%d",&z,&x,&y); // printf("(%lld)",z); if(!map[x])map[x]=++cnt; if(!map[y])map[y]=++cnt; a.c[map[x]][map[y]]=a.c[map[y]][map[x]]=min(a.c[map[x]][map[y]],z); // printf("(%d %d %lld %lld)",map[x],map[y],a.c[map[x]][map[y]],ans.c[map[x]][map[y]]); } // printf("[%d %d %d %d]\n",map[4],map[6],map[8],map[9]); // printf("(%lld)",a.c[map[s]][map[t]]); ans=a;n--;///////不然i,j的值就改成min(k,j)了! for(;n;n>>=1) { if(n&1)ans=ans*a; a=a*a; } printf("%lld",ans.c[map[s]][map[t]]); return 0; }
以上是关于POJ3613 k边最短路的主要内容,如果未能解决你的问题,请参考以下文章