Link:
http://acm.hdu.edu.cn/showproblem.php?pid=2807
Topic:
The shortest Path
Time limit:4000/2000 MS (java/others) Memory limit:32768/32768 K (java/others)
Total submission (s): 1421 accepted submission (s): 436
Problem Description
There are N cities in the country. The represent by a matrix size of m*m. If City A, B and C satisfy which a*b = C, we say that there are a road from a to C with distance 1 (but this does not means There is a road from C to a).
Now the king of the country wants to ask me some problems, in the format:
Is there are a road from city X to Y?
I have to answer the questions quickly, can you help me?
Input
Each test case contains a single integer N, M. indicating the number of cities in the country and the size of all city. The next following N blocks each blocks stands for a matrix size of m*m. Then A integer K means the number of questions the king would ask and the following K lines each contains two integers X, Y (1- Based). The input is terminated by a set starting with N = M = 0. All integers are in the range [0, 80].
Output
For each test case, you should output one line for each question the king asked, if there are a road from city X to Y? Output the shortest distance from X to Y. If not, output "Sorry".
Sample Input
3 2
1 1 2 2 1 1 1 1 2 2 4 4 1 1 3 3 2 1 1 2 2 1 1 1 1 2
2
4 3
1
1 3
0 0
Sample Output
1
Sorry
The main effect of the topic:
If the matrix is a*b=c, then it means that a--B has a one-way path with a distance of 1.
Give some matrices and then ask the direct distance of any two matrices.
Analysis and Summary:
1. The key to this problem is matrix operation.
The first is to build the diagram, obviously, the map to use a 3-layer for loop.
The first time I do it is to put the multiplication of that step in the third layer for loop, resulting in the submission of tle with g++, with C + + submitted with 1500ms+.
And then found that the multiplication can actually be placed in the second loop, the result of an instant from 1500MS to 350ms+
2. The above running time is based on the simple matrix comparison method.
We know that to compare the complexity of two matrices is O (n^2), then is there any way to drop to O (n)? The degree of complexity has been reduced by one step, and the elevation of speed is very objective.
Then looked up the data and learned a method.
This method is mainly to make each matrix multiply by a vector (this vector is <1,2,3,4,... m>), so that the matrix into a one-dimensional identity matrix, then use this identification matrix to determine whether two matrices are equal. Look at the code specifically.
1. Simple matrix comparison, 359MS
359 MS #include <iostream> #include <cstdio> #include <cstring> using namespace std;
typedef int TYPE;
const int INF = 0x7fffffff;
const int VN = 100;
struct matrix{Type MAT[VN][VN];
int n, m;
Matrix () {n=m=vn; memset (Mat, 0, sizeof (MAT));
Matrix (const matrix&a) {set_size (A.N, a.m);
memcpy (Mat, A.mat, sizeof (A.mat));
} matrix& operator = (const Matrix &a) {set_size (A.N,A.M);
memcpy (Mat, A.mat, sizeof (A.mat));
return *this;
} void Set_size (int row, int column) {n=row; m=column;}
Friend Matrix operator * (const matrix &a,const matrix &b) {matrix ret;
Ret.set_size (A.N, B.M); for (int i=0; i<a.n; ++i) {for (int k=0; k<a.m; ++k) if (a.mat[i][k)) {for (int j=0; j< ; b.m; ++J) if (B.mat[k][j]) {ret.mat[i][j] = Ret.mat[i][j]+a.mat[i][k]*b.mat[k][j];
}} return ret;
friend bool operator== (const matrix &a,const matrix &b) {if (A.N!=B.N | | | a.m!=b.m) return FALSE; for (int i=0; i<a.n; ++i) for (int j=0; j<a.m; ++j) if (a.mat[i][j]!=b.mat[i][
J]) return false;
return true;
}
};
Matrix ARR[VN];
int n, m;
int D[VN][VN];
void Init () {for (int i=0; i<n; ++i) {d[i][i] = INF;
for (int j=i+1; j<n; ++j) d[i][j] = d[j][i] = INF;
} void Floyd () {for (int k=0; k<n; ++k) for (int i=0; i<n; ++i) for (int j=0; j<n; ++j)
if (D[i][k]!=inf && d[k][j]!=inf) d[i][j] = min (d[i][j],d[i][k]+d[k][j));
int main () {while (~scanf ("%d%d", &n,&m) &&n+m) {init ();
for (int i=0; i<n; ++i) {arr[i].set_size (m,m); for (int j=0; j<m; ++j) {for (int k=0; k<m; ++k) scanf ("%d", &arr[i].mat [j]
[K]); (int i=0; i<n; ++i) {for (int j=0; j<n; ++j) if (i!=j) {Matr
IX ret = arr[i]*arr[j]; for (int k=0; k<n; ++k) if (k!=j&&k!=i) {if (ret==arr[k)) {D[i][k]
= 1;
}}} Floyd ();
scanf ("%d", &m);
for (int i=0; i<m; ++i) {int u,v;
scanf ("%d%d", &u,&v);
--u,--v;
if (d[u][v]!=inf) printf ("%d\n", D[u][v]);
Else puts ("Sorry");
} return 0; }
2. Fast matrix comparison, 62MS
More Wonderful content: http://www.bianceng.cn/Programming/sjjg/