首页 > 其他分享 >[SCOI2009] 迷路

[SCOI2009] 迷路

时间:2024-09-15 10:13:42浏览次数:7  
标签:原图 迷路 边权 ret int SCOI2009

[SCOI2009] 迷路

题意

给出一张带权有向图,从 \(1\) 号点出发,必须在恰好 \(t\) 时刻到达 \(n\)。

中途不能停留,求有多少种方案。

思路

先考虑边权为 \(1\) 的情况,设 \(f_{t,i,j}\) 为从 \(i\) 走到 \(j\) 花费 \(t\) 个时刻的方案数。

\(f_{t,i,j}=\sum{f_{t-1,i,k} \times f_{t-1,k,j}}\),注意到这就是矩阵乘法的形式,又注意到 \(f_1\) 就是邻接矩阵。

所以 \(f_1^t\) 就是最终矩阵,答案即 \(f_{1,1,n}^{t}\)。

再考虑边权不为 \(1\) 的情况,如何把边权为 \(w\) 的边转化为边权为 \(1\) 的边。

考虑把一个点 \(i\) 拆成 \(10\) 个点 \((i,0),(i,1),\dots,(i,9)\)。

将 \((i,j)\) 向 \((i,j-1)\) 连一条边权为 \(1\) 的边。

如果点 \(i\) 与点 \(j\) 之间有一条边权为 \(w\) 的边,将 \((i,0)\) 向 \((j,w-1)\) 连一条边权为 \(1\) 的边。

因为只有 \((i,0)\) 有出边,\((i,k)\) 想要出去必须先花费 \(k\) 的时间走到 \((i,0)\)。

这样保证了 \((i,0)\) 到 \((j,0)\) 必定花费 \(1+(w-1)=w\) 的时间,与原图等价。

这样我们就把原图转化为了边权为 \(1\) 的图,用邻接矩阵快速幂就能求出答案。

时间复杂度:\(O(n^3)\)。

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 105;
const int M = 2009;
int n, t, cnt, f[N][N], id[N][N];
char str[N];
struct Matrix {
	int h, l, a[N][N];
	void init(int H, int L, bool f) {
		h = H, l = L;
		for (int i = 1; i <= h; i ++)
			for (int j = 1; j <= l; j ++) {
				if (!f) a[i][j] = 0;
				else if (i == j) a[i][j] = 1;
			}
	}
	Matrix operator * (const Matrix& b)const{
		Matrix ret;
		ret.init(h, b.l, 0);
		for (int i = 1; i <= h; i ++)
			for (int j = 1; j <= b.l; j ++) 
				for (int k = 1; k <= l; k ++)
					ret.a[i][j] += a[i][k] * b.a[k][j],
					ret.a[i][j] %= M;
		return ret;
	}
	void input() {
		for (int i = 1; i <= h; i ++)
			for (int j = 1; j <= l; j ++)
				cin >> a[i][j];
	}
	void output() {
		for (int i = 1; i <= h; i ++) {
			for (int j = 1; j <= l; j ++)
				cout << a[i][j] << ' ';
			cout << '\n';
		}
	}
} A, B;
Matrix qpow(Matrix a, int p) {
	Matrix ret;
	ret.init(a.h, a.l, 1);
	for (; p; p >>= 1, a = a * a)
		if (p & 1) ret = ret * a;
	return ret;
}
int main() { 
	scanf("%d%d", &n, &t);
	for (int i = 1; i <= n; i ++) {
		for (int j = 0; j <= 9; j ++) {
			id[i][j] = ++ cnt;
		}
	}
	for (int i = 1; i <= n; i ++) {
		scanf("%s", str + 1);
		for (int j = 1; j <= n; j ++) {
			if (str[j] == '0') continue;
			int w = str[j] - '0';
			f[id[i][0]][id[j][w - 1]] = 1;		
		}
	}
	for (int i = 1; i <= n; i ++) 
		for (int j = 1; j <= 9; j ++) 
			f[id[i][j]][id[i][j - 1]] = 1;
	A.h = A.l = cnt;
	for (int i = 1; i <= cnt; i ++)
		for (int j = 1; j <= cnt; j ++)
			A.a[i][j] = f[i][j];
	A = qpow(A, t);
	printf("%d\n", A.a[id[1][0]][id[n][0]]);
 	return 0;
}

标签:原图,迷路,边权,ret,int,SCOI2009
From: https://www.cnblogs.com/maniubi/p/18415016

相关文章

  • 【网络安全】NISP一级二级备考指南,收藏复习不迷路!(附官方课程+刷题)_nisp二级需要准备多
    作为一名网安人,不考证怎么行呢?今天为大家整理了一份NISP备考指南,教大家如何在最短的时间拿证。收藏加关注,备考不迷路哦!那么,进入正题!NISP属于CISP的校园版,对拿学分、评奖评优、进入事业单位和安全企业都有好处。属于你不一定会用到,但必须有的证书。NISP一级考试共50......
  • Linux网络命令大全,收藏不迷路!
    Linux系统在网络管理中占据重要地位。无论是服务器管理、网络诊断还是安全维护,Linux网络命令都能提供强大的支持。网络配置命令ifconfigifconfig(interfaceconfiguration)是用于配置网络接口的命令。尽管被新的ip命令所取代,但它仍然在很多系统中使用。查看网络接口配置:......
  • 新手装修必备55节课让你避坑不迷路!
    ......
  • P2657 [SCOI2009] windy 数
    原题链接题解一个细节坑我好久code#include<bits/stdc++.h>#definelllonglongusingnamespacestd;llf[15][15]={0};//从最高位第i位数字为j时的数字里有多少windy数llsolve(llnow){now++;//小于等于变小于lllen=0;llnum[15]={0};while(now......
  • [SCOI 2009] 迷路 (矩阵快速幂)
    [SCOI2009]迷路传送门问题描述Windy在有向图中迷路了。该有向图有\({N}\)个节点,Windy从节点\({1}\)出发,他必须恰好在\({T}\)时刻到达节点\({N}\)。现在给出该有向图,你能告诉Windy总共有多少种不同的路径吗?注意:Windy不能在某个节点逗留,且通过某有向边的时间严格......
  • U405333 帕鲁世界迷路的一天 题解
    题目链接:帕鲁世界迷路的一天前置弱化版:P3604美好的每一天题解一个非常简单的普通莫队解很容易写出来,具体的看我前置弱化版题解,然而这个复杂度高达\(O(26n\sqrt{q})\),显然无法通过强化版。一种看上去很正确的“假解”我们思考如何去掉这个\(26\),我们猜想:能够组成\(pre[c......
  • P4159 [SCOI2009] 迷路 题解
    P4159[SCOI2009]迷路搬运工题目链接首先我们先考虑这道题的弱化版如何处理。假如所有的边权都是零和一。这时他们的边权可以看做这两个点走一步到达之间的方案数。而对于走t步,我们可以推出下列式子,\(f_{i,j}\)表示从节点\(i\)到节点\(j\)的方案数。\[f_{i,j}=\su......
  • Health Kit接入资质要求详解,开发不迷路!
    开发运动/健康应用过程中,需要使用HealthKit提供的数据能力,作为独立的个人开发者或是企业开发者,接入时分别需要满足什么样的条件呢?个人开发者接入资质审核要求•个人开发者应用需上架至华为应用市场。个人开发者应用未上架华为应用市场,或者个人开发者应用非移动应用,暂不开放Heal......
  • 洛谷P4158 [SCOI2009] 粉刷匠 题解
    所有的\(DP\),只要式子一推出来(不管复杂度),那就很简单了,因为优化是成千上万种的……思路1:我们考虑设\(f[i][j][k]\)表示:当前\(DP\)到第\(i\)块木板的第\(j\)个位置,共涂了\(k\)次,所能获得的最大收益。因为还要枚举当前这次涂是从哪到哪的,因此复杂度为\(O(NM^2T)\),实......
  • DotNetGuide新增C#/.NET/.NET Core充电站(让你学习不迷路)
    DotNetGuide简介记录、收集和总结C#/.NET/.NETCore基础知识、学习路线、开发实战、学习视频、文章、书籍、项目框架、社区组织、开发必备工具、常见面试题、面试须知、简历模板、以及自己在学习和工作中的一些微薄见解。希望能和大家一起学习,共同进步......