HDU 5607 graph(矩阵快速幂)

本文介绍了一种结合概率动态规划(概率DP)与矩阵快速幂技术解决特定图论问题的方法。通过定义转移矩阵并利用矩阵快速幂进行高效计算,实现了在大规模数据集上求解节点间概率转移的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


类似图上的概率dp


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<string.h>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<ctime>
#include<queue>
#define hash hashh
using namespace std;
typedef long long ll;
#define mod 1000000007

#define sp  system("pause")
#define lchild(i)  2*i
#define rchild(i)  2*i+1
#define getmid(x,y) ((x+y)/2)
#define PB    push_back

class mul
{
public:
	 ll m[100][100];
};

int n,m;
mul  mulM(mul  &x, mul & y)
{
	mul temp;
	for (int i = 1; i <=n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			temp.m[i][j] = 0;
			for (int k = 1; k <= n; k++)
			{
				temp.m[i][j] = (temp.m[i][j] + x.m[i][k] * y.m[k][j] % mod) % mod;
			}
		}
	}
	return temp;
}


ll mod_pow(ll x, ll k)
{
	ll ans = 1;
	while (k)
	{
		if (k & 1)ans *= x, ans %= mod;
		x = (x*x)%mod;
		k >>= 1;
	}
	return ans;
}

vector<ll>G[60];
ll in[60] ;

int main()
{
	while (cin >> n >> m)
	{
		for (int i = 0; i < 60; i++)
			G[i].clear();
		memset(in, 0, sizeof in);
		mul yuan;
		memset(yuan.m, 0, sizeof yuan.m);
		for (int i = 0; i < m; i++)
		{
			int x, y;
			scanf("%d %d", &x, &y);
			yuan.m[y][x] = 1;
			G[y].PB(x);
			in[x]++;
		}
		for (int i = 1; i <= n; i++)
		{
			in[i] = mod_pow(in[i], mod - 2);
		}
		for (int i = 1; i <= n; i++)
		{
			for (int j = 0; j < G[i].size(); j++)
				yuan.m[i][G[i][j]] = (yuan.m[i][G[i][j]] * in[G[i][j]]) % mod;
		}
		int qu;
		cin >> qu;
		while (qu--)
		{
			ll start, k;
			scanf("%lld %lld", &start, &k);
			mul E;
			mul M = yuan;
			memset(E.m, 0, sizeof E.m);
			for (int i = 0; i <= n; i++)
			{
				E.m[i][i] = 1;
			}
			while (k)
			{
				if (k & 1)E = mulM(E, M);
				M = mulM(M, M);
				k >>= 1;
			}
			for (int i = 1; i <= n; i++)
			{
				printf("%lld ", E.m[i][start]);
			}
			printf("\n");
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值