这货就是个坑啊,80^5次方都可以过,数据太水了把。。。
快速矩阵比较:
就是把一个矩阵乘上一个{1,2,3,。。。。m}的向量,得到的矩阵叫做比较阵
这样能顺利把比较的复杂度降到o(n),不过需要注意的两个比较阵相同,不一定意味着两个原来的矩阵一定相同
这个就和hash一样,是有碰撞的,这个原理也就是hash,要是没有碰撞的话,得用80进制,太大了,存不下。
就是这个hash碰撞概率比较小而已,要找到碰撞的话还是很容易的
http://acm.hdu.edu.cn/showproblem.php?pid=2807
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int MAXN=80+10; int n,m; struct Matrix { int v[MAXN][MAXN],c[MAXN]; void cal() { memset(c,0,sizeof(c)); for(int j=0; j<m; j++) for(int i=0; i<m; i++) { c[i]+=v[i][j]*(i+1); } } void init() { memset(v,0,sizeof(v)); } void readin() { for(int i=0; i<m; i++) for(int j =0; j<m; j++) scanf("%d",&v[i][j]); cal(); } bool operator ==(const Matrix &a) const { for(int i=0; i<m; i++) if(c[i]!=a.c[i]) return false; return true; } Matrix operator *(const Matrix &a) const { Matrix ans; ans.init(); for(int i=0; i<m; i++) for(int k=0; k<m; k++) if(v[i][k]) for(int j=0; j<m; j++) ans.v[i][j]+=v[i][k]*a.v[k][j]; ans.cal(); return ans; } }; int G[MAXN][MAXN]; Matrix a[MAXN]; int main() { // freopen("in","r",stdin); int INF; // cout<<pow(80,80)<<endl; while(~scanf("%d%d",&n,&m)) { if(n==0 && m==0 )break; memset(G,0x3f,sizeof(G)); INF=G[0][0]; for(int i=0; i<n; i++) a[i].readin(); for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { if(i==j) continue; Matrix ret=a[i]*a[j]; for(int k=0; k<n; k++) { if(k==i || k==j) continue; if(ret==a[k]) G[i][k]=1; } } } for(int i=0; i<n; i++) G[i][i]=0; for(int k=0; k<n; k++) for(int i=0; i<n; i++) for(int j=0; j<n; j++) G[i][j]=min(G[i][j],G[i][k]+G[k][j]); int q; scanf("%d",&q); while(q--) { int u,v; scanf("%d%d",&u,&v); u--,v--; int ans=G[u][v]; if(ans>=INF) puts("Sorry"); else printf("%d\n",ans); } } return 0; }