现在的位置: 首页 > 综合 > 正文

HDU 2807 The Shortest Path

2013年03月18日 ⁄ 综合 ⁄ 共 1558字 ⁄ 字号 评论关闭

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

题意 : 类似于最短路,不过几个city之间的联系是从他们的矩阵信息中所得到的。(矩阵A * 矩阵B = 矩阵C 则说明A 于 C 之间单向连通并且距离为1,PS : 但是并不是说明B可以连通C,因为矩阵乘法位置互换之后结果不一定相等)

思路 :矩阵乘法复杂度在O(M^3),而枚举每一组A,B,C复杂度又是O(N^3),一开始傻傻的去试了下,果断TLE。好吧,后来把 A * B的结果保存在新的矩阵里,再去寻找是否存在C,使得复杂度大约降到了O(M ^ 3 * N ^ 2),1900MS险过~~~~囧。

PS : 写矩阵的时候最好使用结构体,这样效率高。

//CNWSYCF

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long LL;

const int INF = 100000007;
const double eps = 1e-9;
const int maxn = 100;
#define MIN(a,b) (a > b ? b : a)
#define MAX(a,b) (a > b ? a : b)

struct node
{
      int mat[maxn][maxn];
}q[maxn],temp;
struct gogo
{
      int mat[maxn][maxn];
}New[maxn][maxn];
int N,M,G[maxn][maxn];


bool Pd(int a,int b,int c)
{
      for (int i=1;i<=M;i++)
            for (int j=1;j<=M;j++)
                  if (q[c].mat[i][j] != New[a][b].mat[i][j])return 0;
      return 1;
}

void init()
{
      for (int i=1;i<=N;i++)
            for (int j=1;j<=N;j++)
                  if (i != j)G[i][j] = INF;
                  else G[i][j] = 0;
}

void Floyd()
{
      for (int k=1;k<=N;k++)
            for (int i=1;i<=N;i++)
                  for (int j=1;j<=N;j++)
                        G[i][j] = MIN(G[i][k] + G[k][j] , G[i][j]);
}

void Add(int a,int b)
{
      for (int i=1;i<=M;i++)
            for (int j=1;j<=M;j++)
            {
                  int sum = 0;
                  for (int k=1;k<=M;k++)
                        sum += q[a].mat[i][k] * q[b].mat[k][j];
                  New[a][b].mat[i][j] = sum;
            }
}
int main()
{
      while (scanf("%d%d",&N,&M) && (N || M))
      {
            init();
            for (int c=1;c<=N;c++)
            {
                  for (int i=1;i<=M;i++)
                        for (int j=1;j<=M;j++)
                              scanf("%d",&q[c].mat[i][j]);
            }
            for (int i=1;i<=N;i++)
                  for (int j=1;j<=N;j++)
                        Add(i,j);
            for (int k=1;k<=N;k++)
                  for (int i=1;i<=N;i++)
                        for (int j=1;j<=N;j++)
                              if ((i != j && j!= k && k != i) && Pd(i,j,k))
                              {
                                    G[i][k] = 1;
                                    //G[j][k] = 1;
                              }
            Floyd();
            int Q;
            scanf("%d",&Q);
            while (Q--)
            {
                  int a,b;
                  scanf("%d%d",&a,&b);
                  if (G[a][b] < INF)printf("%d\n",G[a][b]);
                  else printf("Sorry\n");
            }
      }
      return 0;
}

抱歉!评论已关闭.