zoukankan      html  css  js  c++  java
  • 【bzoj1875】[SDOI2009]HH去散步 矩阵乘法

    题目描述

    一张N个点M条边的无向图,从A走到B,要求:每一次不能立刻沿着上一次的的反方向返回。求方案数。

    输入

    第一行:五个整数N,M,t,A,B。
    N表示学校里的路口的个数
    M表示学校里的路的条数
    t表示HH想要散步的距离
    A表示散步的出发点
    B则表示散步的终点。
    接下来M行
    每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。
    数据保证Ai != Bi,但不保证任意两个路口之间至多只有一条路相连接。 
    路口编号从0到N -1。 
    同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。 
    答案模45989。
    N ≤ 20,M ≤ 60,t ≤ 2^30,0 ≤ A,B

    输出

    一行,表示答案。

    样例输入

    4 5 3 0 0
    0 1
    0 2
    0 3
    2 1
    3 2

    样例输出

    4


    题解

    矩阵乘法

    “每一次不能立刻沿着上一次的边的反方向返回”这个条件的限制导致不能直接进行矩阵乘法。

    由于边数很少,我们可以换个思路:把边看作矩阵乘法的行列,矩阵中的元素表示 从一条边走到另一条边的方案数。

    那么对于两条边$i,j$,如果不是刚走过来的边并且能够接上($y_i=x_j$),则$A_{ij}=1$。

    然后建立两个虚点,第一个向起点为s的边连边,起点为t的项第二个连边。

    然后快速幂矩阵乘法即可。

    时间复杂度$O(m^3log t)$

    #include <cstdio>
    #include <cstring>
    #define N 130
    #define mod 45989
    int m , px[N] , py[N];
    struct data
    {
    	int v[N][N];
    	data() {memset(v , 0 , sizeof(v));}
    	int* operator[](int a) {return v[a];}
    	data operator*(data a)
    	{
    		data ans;
    		int i , j , k;
    		for(i = 0 ; i <= m ; i ++ )
    			for(j = 0 ; j <= m ; j ++ )
    				for(k = 0 ; k <= m ; k ++ )
    					ans[i][j] = (ans[i][j] + v[i][k] * a[k][j]) % mod;
    		return ans;
    	}
    }a;
    data pow(data x , int y)
    {
    	data ans;
    	int i;
    	for(i = 0 ; i <= m ; i ++ ) ans[i][i] = 1;
    	while(y)
    	{
    		if(y & 1) ans = ans * x;
    		x = x * x , y >>= 1;
    	}
    	return ans;
    }
    int main()
    {
    	int n , k , s , t , i , j;
    	scanf("%d%d%d%d%d" , &n , &m , &k , &s , &t);
    	for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &px[i << 1] , &py[i << 1]) , px[i << 1 | 1] = py[i << 1] , py[i << 1 | 1] = px[i << 1];
    	m = m * 2 + 1;
    	for(i = 2 ; i <= m ; i ++ )
    	{
    		if(px[i] == s) a[0][i] = 1;
    		if(py[i] == t) a[i][1] = 1;
    		for(j = 2 ; j <= m ; j ++ )
    			if(py[i] == px[j] && (i ^ j) != 1)
    				a[i][j] = 1;
    	}
    	a = pow(a , k + 1);
    	printf("%d
    " , a[0][1]);
    	return 0;
    }
    
  • 相关阅读:
    Java 设计模式——状态模式
    Java 设计模式——外观模式
    Java高级之虚拟机加载机制
    17.1.1.6 Creating a Data Snapshot Using Raw Data Files 创建一个数据快照使用 Raw Data Files
    17.1.1.5 Creating a Data Snapshot Using mysqldump
    17.1.1.4 Obtaining the Replication Master Binary Log Coordinates 得到复制master binary log 位置:
    17.1.1.3 Creating a User for Replication 创建一个用于用于复制:
    17.1.1.2 Setting the Replication Slave Configuration
    17.1.1.1 Setting the Replication Master Configuration 设置复制的master 配置:
    17.1.1 How to Set Up Replication 设置复制:
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7602896.html
Copyright © 2011-2022 走看看