bzoj1297 [SCOI2009]迷路——拆点+矩阵快速幂
2024-08-29 09:49:33
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1297
一看感觉是矩阵快速幂之类的,但边权不好处理啊;
普通的矩阵快速幂只能处理边权为1的,所以想办法把边权处理成1;
仔细一看还有一个条件是边权小于10;
所以拆点!把一个点拆成10个点表示到它不同的距离,那么和它相连的那些点就可以跟某个距离的点连边权为1的边;
虽然没有自己想出来,不过1A还是极好的!(因为太简单了)
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,T,w[][],tot,id[][],mod=;
struct Matrix{
int a[][];
Matrix(){memset(a,,sizeof a);}
Matrix operator * (const Matrix &y) const
{
Matrix x;
for(int i=;i<=tot;i++)
for(int k=;k<=tot;k++)
for(int j=;j<=tot;j++)
(x.a[i][j]+=a[i][k]*y.a[k][j])%=mod;
return x;
}
void init(){for(int i=;i<=tot;i++)a[i][i]=;}
}f,ans;
Matrix pw(Matrix x,int k)
{
Matrix ret; ret.init();
for(;k;k>>=,x=x*x)
if(k&)ret=ret*x;
return ret;
}
int main()
{
scanf("%d%d",&n,&T);
char ch[];
for(int i=;i<n;i++)
{
scanf("%s",&ch);
for(int j=;j<n;j++)
w[i][j]=ch[j]-'';
}
for(int i=;i<n;i++)
for(int j=;j<=;j++)
{
id[i][j]=++tot;
if(j)f.a[tot-][tot]++;
}
for(int i=;i<n;i++)
for(int j=;j<n;j++)
if(w[i][j])f.a[id[i][w[i][j]-]][id[j][]]++;
ans.a[][id[][]]=;
Matrix fn=pw(f,T);
ans=ans*fn;
printf("%d",ans.a[][id[n-][]]);
return ;
}
最新文章
- adb devices 偵測不到 手機
- Mac OS X上搭建伪分布式CDH版本Hadoop开发环境
- 1-MSP430点亮一个灯
- Android so lib库远程http下载和动态注册
- 一看就懂的ReactJs入门教程(精华版)
- memcached windowns 安装使用
- AngularJS中的MVC模式
- ESB概述
- Binder机制1---Binder原理介绍
- 如何一行jquery代码写出tab标签页(链式操作)
- 小米路由器mini如何设置外网访问wan网站的方法
- leetcode medium
- JS 生成唯一数字
- IdentityServer4(7)- 使用客户端认证控制API访问(客户端授权模式)
- Confluence 6 降级你的许可证
- spring boot2+jpa+thymeleaf增删改查例子
- Sed+Grep 快速替换查找字段(批量替换字符串)
- django之class Meta
- Java 构造 BSON 数据类型
- sublime unityshaderplugin