hdu 2254 奥运
来源:互联网 发布:java培训骗局 编辑:程序博客网 时间:2024/04/26 00:07
点击打开hdu 2254
思路: 矩阵乘法
分析:
1 题目给定一个有向图,要求t1-t2天内v1-v2的路径的个数
2 假设有向图的邻接矩阵为A,那么A表示的是有向图中走一步能够到达哪些点的方案数,那么A^n表示的是走n步能够到达哪些点的方案数
3 根据离散数学里面的可达矩阵的性质,我们知道一个有向图的邻接矩阵的前n次幂的和即为可达矩阵,那么要求[t1-t2]之内的路径的条数,因为题目说了t1 = 0的时候为0。那么假设邻接矩阵为A,那么要求的就是A^(t1-1)+A^(t1)+...+A^t2,为什么是从t1-1开始呢,因为邻接矩阵本身代表走一步的结果
3 还有点的范围很大,边数很少,所以我们应该要进行离散化
4 但是数据量很大,对于具体的一组我们应该要事先求出具体的每一个矩阵,然后直接使用即可
代码:
/************************************************ * By: chenguolin * * Date: 2013-08-25 * * Address: http://blog.csdn.net/chenguolinblog * ***********************************************/#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef __int64 int64;const int MOD = 2008;const int MAXN = 10000;const int N = 30;int n , pos;int64 num[2*MAXN];struct Edge{ int64 x; int64 y;};Edge e[MAXN];struct Matrix{ int mat[N][N]; Matrix operator*(const Matrix& m)const{ Matrix tmp; for(int i = 0 ; i < pos ; i++){ for(int j = 0 ; j < pos ; j++){ tmp.mat[i][j] = 0; for(int k = 0 ; k < pos ; k++){ tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD; tmp.mat[i][j] %= MOD; } } } return tmp; }};Matrix ma[MAXN];int search(int64 x){ int left = 0; int right = pos-1; while(left <= right){ int mid = (left+right)>>1; if(num[mid] == x) return mid; else if(num[mid] < x) left = mid+1; else right = mid-1; } return -1;}void init(Matrix &m){ memset(m.mat , 0 , sizeof(m.mat)); sort(num , num+pos); pos = unique(num , num+pos)-num; for(int i = 0 ; i < n ; i++){ int x = search(e[i].x); int y = search(e[i].y); m.mat[x][y]++; }}void Pow(Matrix m){ ma[0] = m; for(int i = 1 ; i < MAXN ; i++) ma[i] = ma[i-1]*m; }void solve(){ Matrix m; init(m); Pow(m); int64 v1 , v2; int k , t1 , t2; scanf("%d" , &k); while(k--){ scanf("%I64d%I64d%d%d" , &v1 , &v2 , &t1 , &t2); if(t1 > t2 || t2 == 0){ puts("0"); continue; } int x = search(v1); int y = search(v2); if(x == -1 || y == -1){ puts("0"); continue; } int sum = 0; for(int i = t1-1 ; i < t2 ; i++){ sum += ma[i].mat[x][y]%MOD; sum %= MOD; } printf("%d\n" , sum); }}int main(){ while(scanf("%d" , &n) != EOF){ pos = 0; for(int i = 0 ; i < n ; i++){ scanf("%I64d%I64d" , &e[i].x , &e[i].y); num[pos++] = e[i].x; num[pos++] = e[i].y; } solve(); } return 0;}
- HDU 2254 奥运
- hdu 2254 奥运
- Hdu 2254 奥运 (矩阵)
- HDU 2254 奥运(矩阵)
- HDU 2254 奥运 矩阵应用
- hdu 2254 奥运(矩阵快速幂)
- HDU - 2254 奥运 (求等比数列和)
- HDU 2254 奥运(数论+矩阵)
- HDU 2544 奥运
- hdu 2254 奥运(矩阵降幂+二分求和)
- hdu 2254 奥运 矩阵求路径方案数
- hdu 2254 奥运(矩阵 感觉挺难的)
- hdu 3789 奥运排序问题
- hdu 3789 奥运排序问题
- HDOJ 2254 - 奥运
- 奥运
- 奥运
- HDU 2254 奥运(矩阵快速幂+二分等比序列求和)
- Java应用程序
- 概率算法求解圆周率π
- 几何方法---测试盒子 二
- TreeView
- ligh oj 1004 - Monkey Banana Problem
- hdu 2254 奥运
- C++模板类的继承1 :模板类继承模板类
- API相关工作的个人总结_Sandcastle简要使用介绍
- Android学习系列-把文件保存到SD卡上面(6)
- HDU4514(非连通图的环判断与图中最长链)
- one of the key features of distributed application-managemeability
- opencv之绘图
- [IOS]包含增删改查移动的tableView展示+plist文件保存+程序意外退出保存Demo
- wikioi p1169 传纸条