首页 > 代码库 > HDU 2254 奥运(矩阵)
HDU 2254 奥运(矩阵)
题目地址:HDU 2254
必须得吐槽一下。。这题的数据是又弱又坑。。样例不过都能AC。。还有。。居然还有重边。。WA了一晚上。。
吐槽完毕,言归正传。。
根据离散数学里面的可达矩阵的性质,我们知道一个有向图的邻接矩阵的前n次幂的和即为可达矩阵,那么要求[t1-t2]之内的路径的条数,因为题目说了t1 = 0的时候为0。那么假设邻接矩阵为A,那么要求的就是A^(t1-1)+A^(t1)+...+A^(t2-1),为什么是从t1-1开始呢,因为邻接矩阵本身代表走一步的结果。
然后再加上离散化就可以做了。
代码如下:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; #define LL __int64 const int mod=2008; int n; LL q[40]; struct matrix { int ma[32][32]; } mat[10002]; matrix Mult(matrix x, matrix y) { int i, j, k; matrix tmp; memset(tmp.ma,0,sizeof(tmp.ma)); for(i=0; i<n; i++) { for(k=0; k<n; k++) { for(j=0; j<n; j++) { tmp.ma[i][j]=(tmp.ma[i][j]+x.ma[i][k]*y.ma[k][j])%mod; } } } return tmp; } int find1(LL x) { int i; for(i=0; i<n; i++) { if(q[i]==x) { return i; } } return -1; } void Pow() { for(int i=1; i<=10001; i++) { mat[i]=Mult(mat[i-1],mat[0]); } } int main() { int m, k, i, j, t1 ,t2, u, v; LL v1, v2; while(scanf("%d",&m)!=EOF) { memset(mat[0].ma,0,sizeof(mat[0].ma)); n=0; while(m--) { scanf("%d%d",&u,&v); int f1=find1(u); if(f1<0) { q[n++]=u; f1=n-1; } int f2=find1(v); if(f2<0) { q[n++]=v; f2=n-1; } mat[0].ma[f1][f2]++; } scanf("%d",&k); Pow(); while(k--) { scanf("%I64d%I64d%d%d",&v1,&v2,&t1,&t2); int f1=find1(v1); int f2=find1(v2); if(f1<0||f2<0) { puts("0"); continue ; } int ans=0; for(i=t1-1; i<t2; i++) { if(i==-1) continue ; ans+=mat[i].ma[f1][f2]%mod; ans%=mod; } printf("%d\n",ans); } } return 0; }
HDU 2254 奥运(矩阵)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。