csu 1831: Found

来源:互联网 发布:淘宝买花苗 编辑:程序博客网 时间:2024/06/04 08:34

题目链接点这里

大意:一张无向图(点数n<=10),初始一个人在1点,还有个人在n点,每一个单位时间每人都必须往相邻的点移动,求k时间后两人在同一地点的路线数(k之前不能相遇)

看到这么大的数据量,就应该想到快速幂了吧

吧节点从0标号,就可以吧2个人的状态压缩到一个2位数,,比如第一个人在3,第二个人在5就可以用 24这个数表示,,

就构成100*100的一个状态转移矩阵

然后就是快速幂了

#include<cstdio>#include<cstring>#include<set>#include<time.h>#include<iostream>#include<math.h>#include<algorithm>#include<queue>using namespace std;#define MX  111#define INF 0x3f3f3f3f#define mem(x,y) memset(x,y,sizeof(x))#define fuck(x)  cout<<x<<endltypedef  long long LL;typedef  pair<int,int > PII;const int p=9973;int n,m;LL k;int head[MX],cnt;struct Edge{    int nxt,to;} E[2*MX];void edge_init(){    mem(head,-1);    cnt=0;}void edge_add(int u,int v){    E[cnt].nxt=head[u];    E[cnt].to=v;    head[u]=cnt++;}struct Matrix{    int a[100][100],n;    void init(int _n)    {        n=_n;        for(int i=0; i<n; i++)            for(int j=0; j<n; j++) a[i][j]=0;    }    Matrix operator *(const Matrix w)const    {        Matrix A;        A.init(w.n);for(int k=0; k<n; k++)        for(int i=0; i<n; i++)             for(int j=0; j<n; j++) A.a[i][j]=(A.a[i][j]+(a[i][k]*w.a[k][j]))%p;        return A;    }};void build(Matrix &A,Matrix &B){    for(int i=0; i<n; i++)        for(int j=0; j<n; j++)            if(i!=j)                for(int ii=head[i]; ~ii; ii=E[ii].nxt)                {                    int v=E[ii].to;                    for(int jj=head[j]; ~jj; jj=E[jj].nxt)                    {                        int vv=E[jj].to;                        if(vv==v)B.a[i*10+j][v*10+v]=1;                        else B.a[i*10+j][v*10+vv]=A.a[i*10+j][v*10+vv]=1;                    }                }}void print(Matrix A){    for(int i=0; i<A.n; i++)        for(int j=0; j<A.n; j++) printf("%d%c",A.a[i][j],j==A.n-1?'\n':' ');}Matrix quick_Matrix(Matrix A,LL x){    Matrix B;    B.init(A.n);    for(int i=0; i<B.n; i++) B.a[i][i]=1;    while(x)    {        if(x&1) B=B*A;        A=A*A;        x>>=1;    }    return  B;}int main(){    int _;    cin>>_;    while(_--)    {        cin>>n>>m>>k;        edge_init();        for(int i=1; i<=m; i++)        {            int u, v;            scanf("%d%d",&u,&v);            u--;            v--;            edge_add(u,v);            edge_add(v,u);        }        Matrix A,B;        A.init((n-1)*10+(n-1)+1);        B.init((n-1)*10+(n-1)+1);        build(A,B);        //print(A);        // fuck('\n');        // print(B);        B=quick_Matrix(A,k-1)*B;        // print(B);        int ans=0;        for(int i=0; i<n; i++) ans=(ans+B.a[n-1][i*10+i])%p;        printf("%d\n",ans);    }    return 0;}


1 0