HDU 2807 the shortest Path: shortest circuit + matrix quick Comparison

Source: Internet
Author: User
Tags comparison integer time limit

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&lt ; 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/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.