hdu 2254(矩阵)

题意:指定v1,v2,要求计算出在t1,t2天内从v1->v2的走法

思路:可以知道由矩阵求,即将其建图A,求矩阵A^t1 + ...... + A^t2.   A^n后,/*A.xmap[v1][v2]即是从v1到v2要n步

所以先预处理出A^1 -A^10000的情况,后面再注意下细节,计算即可.


(每条道路走需要花一天的时间,且不能在某个城市停留,且t1=0时的走法数为0)

开始以为只要t1 = 0就输出0,结果不停WA,一直对照别人的代码- -

结果偶然发现这个特例,它喵的我也是醉了,才发现是题意理解错了,好惨...Orz

  1. 特例: 
  2.     Input: 
  3.     1 
  4.     1 1 
  5.     1  
  6.     1 1 0 1 
  7.     Ouput: 
  8.     1 
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<functional>
using namespace std;
typedef long long ll;
const int mod=2008;
const int maxn=5e5;
map<int,int>has;
struct Maxtri
{
    int xmap[30][30];
};
int siz;
Maxtri mat[10005];

Maxtri Mul(Maxtri &a,Maxtri &b)
{
    Maxtri c;
    for(int i=0; i<siz; i++)
    {
        for(int j=0; j<siz; j++)
        {
            c.xmap[i][j]=0;
            for(int k=0; k<siz; k++)
            {
                c.xmap[i][j]+=a.xmap[i][k]*b.xmap[k][j];
                c.xmap[i][j]%=mod;
            }
        }
    }
    return c;
}


int main()
{
    int n,u,v,k;

    int v1,v2,t1,t2;
    while(scanf("%d",&n) != EOF)
    {
        siz = 0;
        memset(mat[0].xmap,0,sizeof(mat[0].xmap));
        has.clear();
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d",&u,&v);
            if(has.find(u)==has.end())
            {
                has[u]=siz++;
            }
            if(has.find(v)==has.end())
            {
                has[v]=siz++;
            }
            mat[0].xmap[has[u]][has[v]]  ++;
        }


        for(int i=1; i<10001; i++)
            mat[i]=Mul(mat[i-1],mat[0]);
        scanf("%d",&k);
        while(k--)
        {
            scanf("%d%d%d%d",&v1,&v2,&t1,&t2);
            if(has.find(v1)==has.end()||has.find(v2)==has.end() || (!t1 && !t2))
            {
                printf("0
");
                continue;
            }
            if(t1 > t2)
               swap(t1,t2);

            int ans=0;
            for(int i=t1-1; i<t2; i++)
            {
                if(i == -1)
                    continue;
                ans= (ans + mat[i].xmap[has[v1]][has[v2]])%mod;
            }
            printf("%d
",ans%mod);
        }
    }
    return 0;
}