• 【bzoj4887】[Tjoi2017]可乐 矩阵乘法


    题目描述

    加里敦星球的人们特别喜欢喝可乐。因而,他们的敌对星球研发出了一个可乐机器人,并且放在了加里敦星球的1号城市上。这个可乐机器人有三种行为:停在原地,去下一个相邻的
    城市,自爆。它每一秒都会随机触发一种行为。现在给出加里敦星球城市图,在第0秒时可乐机器人在1号城市,问经过了t秒,可乐机器人的行为方案数是多少?

    输入

    第一行输入两个正整数N,M表示城市个数,M表示道路个数。(1≤N≤30,0≤M≤100)
    接下来M行输入u,v表示u,v之间有一条道路。
    (1≤u,v≤n)保证两座城市之间只有一条路相连。
    最后输入时间t。1<t≤10^6

    输出

    输出可乐机器人的行为方案数,答案可能很大,请输出对2017取模后的结果。

    样例输入

    3 2
    1 2
    2 3
    2

    样例输出

    8


    题解

    矩阵乘法

    傻逼题,显然邻接矩阵自乘。对于停留,每个点连一个自环;对于自爆,每个点向虚拟节点连边,虚拟节点连自环。

    矩阵的 $t$ 次幂的第一行的和即为答案。

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

    #include <cstdio>
    #include <cstring>
    int n;
    struct data
    {
    	int v[35][35];
    	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 <= n ; i ++ )
    			for(k = 0 ; k <= n ; k ++ )
    				for(j = 0 ; j <= n ; j ++ )
    					ans[i][j] = (ans[i][j] + v[i][k] * a[k][j]) % 2017;
    		return ans;
    	}
    }A;
    data pow(data x , int y)
    {
    	data ans;
    	int i;
    	for(i = 0 ; i <= n ; i ++ ) ans[i][i] = 1;
    	while(y)
    	{
    		if(y & 1) ans = ans * x;
    		x = x * x , y >>= 1;
    	}
    	return ans;
    }
    int main()
    {
    	int m , k , i , x , y , ans = 0;
    	scanf("%d%d" , &n , &m);
    	for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &x , &y) , A[x][y] = A[y][x] = 1;
    	for(i = 1 ; i <= n ; i ++ ) A[i][i] = A[i][0] = 1;
    	A[0][0] = 1;
    	scanf("%d" , &k) , A = pow(A , k);
    	for(i = 0 ; i <= n ; i ++ ) ans = (ans + A[1][i]) % 2017;
    	printf("%d
    " , ans);
    	return 0;
    }
    
  • 相关阅读:
    vue项目搭建步骤
    文件的操作总结
    WPF 使用皮肤影响按钮自定义
    WPF中:未找到可以 register Name“XXX”的 NameScope
    WPF Label或者其他控件(以Content显示内容的)单个下划线不显示的问题。
    wpf 中GridControl后面总是多一空白列
    WPF设置控件层次问题(最顶层,最底层)
    WPF中设置TreeView的高度随着窗口改变
    C# 检测文件是否被其他进程占用
    XML文件的操作
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8681108.html
Copyright © 2020-2023  润新知