poj 3613 Cow Relays【矩阵快速幂+Floyd】

!:自环也算一条路径
矩阵快速幂,把矩阵乘法的部分替换成Floyd(只用一个点扩张),这样每“乘”一次,就是经过增加一条边的最短路,用矩阵快速幂优化,然后因为边数是100级别的,所以把点hash一下最多剩下200个

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=205,inf=1e9;
int n,m,s,t,g[N],tot,x[N],y[N],z[N],h[1005],has;
struct jz
{
    int a[N][N];
    jz operator * (const jz &b) const
    {
        jz c;
        for(int i=1;i<=has;i++)
            for(int j=1;j<=has;j++)
                c.a[i][j]=inf;
        for(int k=1;k<=has;k++)
            for(int i=1;i<=has;i++)
                for(int j=1;j<=has;j++)
                    c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
        return c;
    }
}a,r;
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&z[i],&x[i],&y[i]);
        g[++tot]=x[i],g[++tot]=y[i];
    }
    sort(g+1,g+1+tot);
    for(int i=1;i<=tot;i++)
        if(i==1||g[i]!=g[i-1])
            h[g[i]]=++has;
    for(int i=1;i<=has;i++)
        for(int j=1;j<=has;j++)
            a.a[i][j]=inf;
    for(int i=1;i<=m;i++)
        a.a[h[x[i]]][h[y[i]]]=a.a[h[y[i]]][h[x[i]]]=min(z[i],a.a[h[y[i]]][h[x[i]]]);//,cerr<<h[y[i]]<<" "<<h[x[i]]<<" "<<z[i]<<endl;
    s=h[s],t=h[t];
    r=a;
    n--;
    while(n)
    {
        if(n&1)
            r=r*a;
        a=a*a;
        n>>=1;
    }
    printf("%d\n",r.a[s][t]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lokiii/p/9275814.html