码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3613 k边最短路

时间:2018-04-12 00:11:08      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:ret   http   code   重载   一个   using   AC   struct   cstring   

题目: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边最短路

标签:ret   http   code   重载   一个   using   AC   struct   cstring   

原文地址:https://www.cnblogs.com/Narh/p/8799282.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!