弱校联盟#con3--Ancient Tomb Adventures

来源:互联网 发布:linux mysql 安装包 编辑:程序博客网 时间:2024/05/22 16:01

http://oj.neu.edu.cn/problem/792
One day, Tank goes to explore an ancient tomb. However, when he enters the tomb, the entry is suddenly locked. As he is very frightened, a strange sound comes and says:” Human, welcome to my tomb. You can stay in the tomb for no more than t days. If t days later you do not reach the exit room, the whole tomb will collapse and you will be buried to death! Hahahaha…… But in the t days you can go to all rooms and do what you want to. Remember, once you reach the exit room, you will be transferred outside the tomb by force and can not come back. Here is the map of the tomb. Good luck!”
Seeing the map, Tank finds that the tomb is made up of n rooms, numbers from 1. There are m undirected roads, each of which connects two of the room. Due to the limit of the energy, Tank can only travel no more than r roads in a day.

Now can you find out how many ways can Tank exit the tomb? Two ways are considered different if and only if the days that Tank stays in the tomb are different or there exists one day that the length of the two sequences of the room that Tank explores are different or there exists one day that there exist one place on the two sequences of the room that Tank explores are different

题意:

多少种方法在不超过t天,每天走不超过r条路的情况下从s到达e(中途不经过e)

tip:

用邻接矩阵建图,但由于中途不能经过e,因此与e有关的边是单向的指向e,其余边是双向的。邻接矩阵建图时候,如果两点可达就是1(有重边就是边的数量)没有重边就是0.。。这样建好的邻接矩阵A,就是走一步之后可能的状态,加上A^0就是走了一步或者没有走,A^2就是两步,可以理解为如果A(a,c)不为0 则一定存在A(a,b)*A(b,c)不为0 也就是说有a->b&&b->c的路径,于是最后也可以理解出来A(s,t)就是s起点到t终点的。。。
则一天内从一点到达另一点的方案数的矩阵D=A^0+A^1+A^2+…+A^r,
而本题比较不一样的地方在于一旦到达了终点就不可能转移到别的地方了,所以我们把A^0正常是个单位矩阵的(T,T)终点变为0 这就是不让他转移到别的终点位置,也就是一步没走的时候不能走到终点(除非s=t,特判) 这时候的D就是走一天可能的样子,也就是每天都可能这样。最后S = D^1+D^2+…+D^t,就是答案

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const long long MOD = 1e9+7 ;const int maxn = 25;int n,m,t,r;int S,T;struct Matrix{    long long m[maxn][maxn];    void print(){        for(int i=1;i<=n;i++){            for(int j=1;j<=n;j++)cout<<m[i][j]<<" ";            cout<<"\n";        }    }}mp,day[maxn],ans,E,fE;Matrix Mul(Matrix a ,Matrix b){    Matrix tmp;    memset(tmp.m,0,sizeof(tmp.m));    for(int i = 1 ; i <= n ; i++)        for(int j = 1 ; j <= n ;j++)            for(int k = 1 ; k <= n; k++)                tmp.m[i][j] = (tmp.m[i][j]+a.m[i][k]*b.m[k][j])%MOD ;    return tmp;}Matrix qpow(Matrix a,long long nn){    Matrix tmp;    memset(tmp.m,0,sizeof(tmp.m));    for(long long i = 1 ; i <= n ;i++)        tmp.m[i][i] = 1;    while(nn){        if(nn & 1)            tmp = Mul(tmp,a);        nn >>= 1;        a = Mul(a,a);    }    return tmp;}void init(){    memset(mp.m,0,sizeof(mp.m));    for(int i = 1; i <= m ; i++){        int u,v;        scanf("%d%d",&u,&v);        mp.m[u][v] = mp.m[v][u] = 1;    }    scanf("%d%d",&S,&T);    for(int i = 1; i <= n ; i++) mp.m[T][i]=0;    memset(E.m,0,sizeof(E.m));    memset(fE.m,0,sizeof(fE.m));    for(int i = 1; i <= n ; i++)        E.m[i][i] = 1,fE.m[i][i] = MOD-1;}Matrix add(Matrix A,Matrix B){    Matrix tmp;    memset(tmp.m,0,sizeof(tmp.m));    for(int i = 1; i <= n ; i++)        for(int j= 1; j <= n ; j++)            tmp.m[i][j] = (A.m[i][j]+B.m[i][j])%MOD;    return tmp;}//D = A^0+A^1+A^2+…+A^r//1+A+A^2+...+A^{2n-1} = (I+A+A^2+...+A^{n-1})*(I+A^n)Matrix sum(Matrix mp, int r){    if(r == 1)  return add(E,mp);    else if(r % 2 == 1){        Matrix tmp = sum(mp,r/2);        tmp = Mul(tmp,add(E,qpow(mp,(r/2+1))));        return tmp;    }    else{        Matrix tmp = sum(mp,r-1);        tmp = add(tmp,qpow(mp,r));        return tmp;    }}void sov(){    Matrix tmp = sum(mp,r);    tmp.m[T][T] = (tmp.m[T][T] + MOD - 1) % MOD;    tmp = sum(tmp,t);    tmp = add(tmp,fE);    cout<<tmp.m[S][T]<<endl;}//S=D^0+D^1+D^2+…+D^tint main(){    while ( 4 == scanf("%d%d%d%d",&n,&m,&t,&r) ) {        init();        if(S == T)  printf("1\n");        else            sov();    }    return 0;}//3 2 10 10 1 2 2 3 1 3
0 0
原创粉丝点击