hdu shortest path 快速矩阵比较 + 最短路

来源:互联网 发布:为什么彩虹岛网络异常 编辑:程序博客网 时间:2024/05/16 17:45

这货就是个坑啊,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;}


0 0