疯子的算法总结(九) 图论中的矩阵应用 Part 1 POJ3613 Cow Relays
图的存储有邻接矩阵,那么他就具备一些矩阵的性质,设有一个图的demo[100][100];那么demo[M][N]就是M—>N的距离,若经过一次松弛操作demo[M][N]=demo[M][K]+demo[K][N],即为demo[M][N]经过了两条条边的最小距离,floyd是 demo[M][N]=Min(demo[M][K]+demo[K][N],demo[M][N]),有可能两点之间直接距离最短,不经过第三边,那我们不考虑不经过两点之间的情况,那么demo[M][N]等于 demo[M][K]+demo[K][N] 枚举K的最小值,于是出现了一类问题,叫做两点之间经过N条边的最短距离,那么类比矩阵乘法,矩阵乘法是求和,我们在这里是求最小值,那么可以改造矩阵乘法得出,不是Floyd,K放在外面和里面没有区别,放外面像是Floyd,放里面就是标准的矩阵乘法,因为这个只用一次,所有对于枚举的状态是等价的。
for(int k=1; k<=cnt; k++)
{
for(int i=1; i<=cnt; i++)
{
for(int j=1; j<=cnt; j++)
{
c[i][j]=Min(a[i][k]+b[k][j],c[i][j]);
}
}
}
每做一次类矩阵乘法,就代表将M,N松弛后多一条经过边,那么经过T次松弛后就会得到N,M经过T条边的最短距离,既然是类矩阵乘法,是不是遵循结合律呢?答案是的。对于矩阵
,前面是经过T条边的最小值,后边是经过W条边的最小值,想乘代表经过了T+W条边的最小值,因为每进行一次都是插入一个点,即使点重复,那么他也会有环形出现,但还是经过了T+W条边,如此,我们可以利用矩阵快速幂求解其经过N条边之后的最小值,那么我们会发现矩阵跟图的是密不可分,一定还会有其他的特点去等待发现,它还可以用于求解图的生成树问题,下次更新。
本思想可以解决POJ3613,好像现在题没了,给一个网站https://www.acwing.com/problem/content/347/,代码附在下方。
#include<iostream>
#include<queue>
#include<algorithm>
#include<set>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<bitset>
#include<cstdio>
#include<cstring>
#define Swap(a,b) a^=b^=a^=b
#define cini(n) scanf("%d",&n)
#define cinl(n) scanf("%lld",&n)
#define cinc(n) scanf("%c",&n)
#define cins(s) scanf("%s",s)
#define coui(n) printf("%d",n)
#define couc(n) printf("%c",n)
#define coul(n) printf("%lld",n)
#define speed ios_base::sync_with_stdio(0)
#define Max(a,b) a>b?a:b
#define Min(a,b) a<b?a:b
#define mem(n,x) memset(n,x,sizeof(n))
#define INF 0x3f3f3f3f
#define maxn 100010
#define esp 1e-9
#define mp(a,b) make_pair(a,b)
using namespace std;
const int N=300;
#define clr(a) memset(a,0,sizeof(a))
int a[N][N],temp[N][N],ans[N][N];
int used[10*N];
int p[10*N];
void floyed(int a[][N],int b[][N],int c[][N],int cnt)
{
for(int k=1; k<=cnt; k++)
{
for(int i=1; i<=cnt; i++)
{
for(int j=1; j<=cnt; j++)
{
c[i][j]=Min(a[i][k]+b[k][j],c[i][j]);
}
}
}
}
void copy(int n,int a[][N],int b[][N])
{
for(int i=0; i<=n; i++)
for(int j=0; j<=n; j++)
a[i][j]=b[i][j],b[i][j]=INF;
}
int solve(int s,int t,int n,int cnt)
{
while(n)
{
if(n&1)
{
floyed(ans,a,temp,cnt);
copy(cnt,ans,temp);
}
floyed(a,a,temp,cnt);
copy(cnt,a,temp);
n>>=1;
}
return ans[s][t];
}
int main()
{
int n,t,S,E;
scanf("%d%d%d%d",&n,&t,&S,&E);
int u,v,w;
int cnt=0;
mem(ans,0x3f);
mem(temp,0x3f);
mem(a,0x3f);
for(int i=0; i<t; i++)
{
scanf("%d%d%d",&w,&u,&v);
if(!used[u])
{
used[u]=1;
p[u]=++cnt;
a[cnt][cnt]=temp[cnt][cnt]=ans[cnt][cnt]=0;
}
if(!used[v])
{
used[v]=1;
p[v]=++cnt;
a[cnt][cnt]=temp[cnt][cnt]=ans[cnt][cnt]=0;
}
a[p[u]][p[v]]=a[p[v]][p[u]]=w;
}
printf("%dn",solve(p[S],p[E],n,cnt));
return 0;
}
这个题的边不连续,要先离散化。
- [OIDC in Action] 1. 基于OIDC(OpenID Connect)的SSO
- [OIDC in Action] 2. 基于OIDC(OpenID Connect)的SSO(纯JS客户端)
- [认证授权] 2.OAuth2授权(续) & JWT(JSON Web Token)
- [Cake] 0.C#Make自动化构建-简介
- [认证授权] 3.基于OAuth2的认证(译)
- [Asp.Net Core] 1. IIS中的 Asp.Net Core 和 dotnet watch
- kafka数据迁移实践
- HDFS 2.x 磁盘间数据均衡的一种可行办法
- Batik渲染png图片异常的bug修复全程记录
- Web应用服务器安全:攻击、防护与检测
- 基于Go Packet实现网络数据包的捕获与分析
- 动态追踪技术(四):基于 Linux bcc/BPF 实现 Go 程序动态追踪
- Hive 时间转换函数使用心得
- Flume-Hbase-Sink针对不同版本flume与HBase的适配研究与经验总结
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 29.opengl高级光照-视差贴图
- SpringBoot集成Mybatis开启下划线格式的数据自动转换成小驼峰格式
- WPF 列表右键菜单比较符合 MVVM 的命令绑定方法
- Group Sample:一个简单有效的目标检测涨点Trick
- PyTorch版CenterNet数据加载解析
- WPF 使用 HandyControl 给 ListView 添加漂亮的表头效果
- kali2020 忘记密码
- 低比特量化之DoreFa-Net理论与实践
- 不用数组求多个数的最小值
- 小程序 Tip | 文档、环境、开发工具界面与特性
- 大佬的思路就是不一样,这是我见过最简洁又清晰的SSM框架整合
- SQL Server重置自增的值为0
- 被经理邀请去“爬山”,只是因为我写错了一条SQL语句?
- Maven环境配置-必会
- Centos7中Docker安装RabbitMQ