http://acm.hdu.edu.cn/showproblem.php?pid=2807

把矩阵相乘放在第二重循环,第三重循环只进行比较可以水过,优化的方法不懂

主要用这题练习floyd的写法

#include <iostream>
#include <cstdio>
using namespace std ;
const int INF=0xfffffff ;
int n,m ;
int dis[85][85] ;
int M[85][85][85],c[85][85] ;
void mul(int a[85][85],int b[85][85])
{
    int i,j,k ;
    for(i=0 ;i<m ;i++)
        for(j=0 ;j<m ;j++)
            c[i][j]=0 ;
    for(i=0 ;i<m ;i++)
        for(j=0 ;j<m ;j++)
            for(k=0 ;k<m ;k++)
                c[i][j]=c[i][j]+a[i][k]*b[k][j] ;
}
int cmp(int x)
{
    for(int i=0 ;i<m ;i++)
        for(int j=0 ;j<m ;j++)
            if(c[i][j]!=M[x][i][j])
                return 0 ;
       return 1 ;
}
void floyd()
{
    for(int k=1 ;k<=n ;k++)
        for(int i=1 ;i<=n ;i++)
            for(int j=1 ;j<=n ;j++)
                dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]) ;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        if(!n && !m)break ;
        for(int i=1 ;i<=n ;i++)
        {
            for(int j=1 ;j<=n ;j++)
            {
                if(i==j)dis[i][j]=0 ;
                else dis[i][j]=dis[j][i]=INF ;
            }
        }
        for(int i=1 ;i<=n ;i++)
        {
            for(int j=0 ;j<m ;j++)
            {
                for(int k=0 ;k<m ;k++)
                {
                    scanf("%d",&M[i][j][k]) ;
                }
            }
        }
        for(int i=1 ;i<=n ;i++)
        {
            for(int j=1 ;j<=n ;j++)
            {
                if(i==j)continue ;
                mul(M[i],M[j]) ;
                for(int k=1 ;k<=n ;k++)
                {
                    if(i==k || j==k)continue ;
                    if(dis[i][k]==1)continue ;
                    if(cmp(k))
                    {
                        dis[i][k]=1 ;
                    }
                }
            }
        }
        floyd() ;
        int k ;
        scanf("%d",&k) ;
        while(k--)
        {
            int s,t ;
            scanf("%d%d",&s,&t) ;
            if(dis[s][t]!=INF)printf("%d\n",dis[s][t]) ;
            else puts("Sorry") ;
        }
    }
    return 0 ;
}
View Code