疯子的算法总结(九) 图论中的矩阵应用 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=; k<=cnt; k++)
- {
- for(int i=; i<=cnt; i++)
- {
- for(int j=; 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=;
- #define clr(a) memset(a,0,sizeof(a))
- int a[N][N],temp[N][N],ans[N][N];
- int used[*N];
- int p[*N];
- void floyed(int a[][N],int b[][N],int c[][N],int cnt)
- {
- for(int k=; k<=cnt; k++)
- {
- for(int i=; i<=cnt; i++)
- {
- for(int j=; 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=; i<=n; i++)
- for(int j=; 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&)
- {
- floyed(ans,a,temp,cnt);
- copy(cnt,ans,temp);
- }
- floyed(a,a,temp,cnt);
- copy(cnt,a,temp);
- n>>=;
- }
- 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=;
- mem(ans,0x3f);
- mem(temp,0x3f);
- mem(a,0x3f);
- for(int i=; i<t; i++)
- {
- scanf("%d%d%d",&w,&u,&v);
- if(!used[u])
- {
- used[u]=;
- p[u]=++cnt;
- a[cnt][cnt]=temp[cnt][cnt]=ans[cnt][cnt]=;
- }
- if(!used[v])
- {
- used[v]=;
- p[v]=++cnt;
- a[cnt][cnt]=temp[cnt][cnt]=ans[cnt][cnt]=;
- }
- a[p[u]][p[v]]=a[p[v]][p[u]]=w;
- }
- printf("%d\n",solve(p[S],p[E],n,cnt));
- return ;
- }
这个题的边不连续,要先离散化。
疯子的算法总结(九) 图论中的矩阵应用 Part 1+POJ3613 Cow Relays的更多相关文章
- 疯子的算法总结(九) 图论中的矩阵应用 Part 2 矩阵树 基尔霍夫矩阵定理 生成树计数 Matrix-Tree
定理: 1.设G为无向图,设矩阵D为图G的度矩阵,设C为图G的邻接矩阵. 2.对于矩阵D,D[i][j]当 i!=j 时,是一条边,对于一条边而言无度可言为0,当i==j时表示一点,代表点i的度. 即 ...
- 【算法】关于图论中的最小生成树(Minimum Spanning Tree)详解
本节纲要 什么是图(network) 什么是最小生成树 (minimum spanning tree) 最小生成树的算法 什么是图(network)? 这里的图当然不是我们日常说的图片或者地图.通常情 ...
- 图论中最优树问题的LINGO求解
树:连通且不含圈的无向图称为树.常用T表示.树中的边称为树枝,树中度为1的顶点称为树叶. 生成树:若T是包含图G的全部顶点的子图,它又是树,则称T是G的生成树. 最小生成树:设T=(V,E1)是赋权图 ...
- ZeroMQ接口函数之 :zmq_z85_decode – 从一个用Z85算法生成的文本中解析出二进制密码
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_z85_decode zmq_z85_decode(3) ØMQ Manual - ØMQ/4.1 ...
- 相机标定:关于用Levenberg-Marquardt算法在相机标定中应用
LM算法在相机标定的应用共有三处. (1)单目标定或双目标定中,在内参固定的情况下,计算最佳外参.OpenCV中对应的函数为findExtrinsicCameraParams2. (2)单目标定中,在 ...
- 算法效果AB测试中的PV-UV不对称性
(转载请注明原创于潘多拉盒子) 算法效果的AB测试,是指在相同的应用场景下,对比不同算法的效果.通常的做法是,按照PV或UV随机分配流量到算法上,计算算法的CTR或转化率进行对比.为了表述简单,我们假 ...
- C++11新特性应用--介绍几个新增的便利算法(不更改容器中元素顺序的算法)
总所周知.C++ STL中有个头文件,名为algorithm.即算法的意思. The header<algorithm>defines a collection of functions ...
- java排序算法(九):归并排序
java排序算法(九):归并排序
- 机器学习、深度学习、和AI算法可以在网络安全中做什么?
本文由 网易云发布. 本文作者:Alexander Polyakov,ERPScan的首席技术官和联合创始人.EAS-SEC总裁,SAP网络安全传播者. 现在已经出现了相当多的文章涉及机器学习及其保 ...
随机推荐
- python调用js
安装 pip install PyExecJS 方法 eval() 输入参数:source(JS语句).cwd(路径) 返回值:result(语句执行结果) compile() 输入参数:source ...
- "字符反向拼接"组件:<reverse> —— 快应用组件库H-UI
 <import name="reverse" src="../Common/ui/h-ui/text/c_text_reverse"></ ...
- cmake添加版本号
vVersion.cmake文件内容如下: #vversion.cmake #vDateTime string(TIMESTAMP vDateTime "%Y%m%d-%H%M%S" ...
- golang 在 Mac , Linux , Windows 下交叉编译详解
一. 前言 Golang 支持交叉编译, 在一个平台上生成然后再另外一个平台去执行. 而且编译的工具[build]这个工具是Golang 内置的,不需要你去下载第三方的包啥的,贼方便. 二. 交叉编译 ...
- loadrunner vuser 限制修改
- 【Java】封装、继承、多态
封装 在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代 ...
- 胜利大逃亡 BFS
Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0 ...
- Matlab学习-(4)
1. 函数 1.1 原始方法 之前我调用函数的方法是,首先写好函数文件,然后保存,然后在主函数中调用.这种方法的不足在于会导致你的工作目录的文件太多,从而导致很乱.在网上找了一些解决方法. 1.2 本 ...
- CentOS 使用中问题记录
⚠️使用yum提示Error: rpmdb open failed的解决方案 清除原rpmdb文件,这一步可能不用操作,直接进行第2步 # rm -f /var/lib/rpm/__db.* 重建rp ...
- Mysql列属性
列属性又称之为字段属性在mysql中一共有6个属性:null,默认值(default),列描述(comment),主键(primary key),唯一键(unique key)和自动增长 修改数据库字 ...