图论总结
图论定义:图G=(V,E)是一个二元组(V,E)使得E⊆[V]的平方,所以E的元素是V的2-元子集。为了避免符号上的混淆,我们总是默认V∩B=Ø。集合V中的元素称为图G的定点(或节点、点),而集合E的元素称为边(或线)。
图论外貌:
( 有点丑别建议哈)
图论特性:没有模板不能活,老死不相往来。
建图方法:边表,邻接矩阵
边表:一般用结构体存储
struct note
{
int y,next,v;//y节点,next下一个,v之间的权值。
}a[E+8]//E为边数
邻接矩阵:用二维数组
bool f[][];//好用极了,但耗空间。表示i与j是否相连。
图论用法:
最短路:共有四种算法:Floyd,Dijkstra,Bellman_Ford,SPFA;
Floyd:是最短四算法中最简单的,但效率不咋地。
主体思路:i点如果和j点相连且j点和k点相连,那么i点和k点相连
优点:容易敲,容易理解,可以处理负权。
缺点:效率低O(n^3),不能处理负环。
void floyd(){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
if(d[i][k]+d[k][j]<d[i][j]){
d[i][j]=d[i][k]+d[k][j];//只能用邻接矩阵
path[i][j]=k;
}
}
Dijkstra:是最短四算法中效率最高的(Orz,这是谁想出的,辣膜流)
主体思想:使用了广度优先搜索策略,以起始点为中心向外层层扩展,直到扩展到终点为止。
优点:因为遍历是节点多,效率较高O(n^2)
缺点:不能处理负权,且代码复杂。
void dijkstra(int r){
for(int i=1;i<=n;i++)dis[i]=a[r][i];//还是用邻接矩阵,但也可以用邻接表
memset(vis,false,sizeof(vis));//vis用于标记
vis[r]=true;dis[r]=0;//起点赋值
for(int i=1;i<n;i++)//只要循环n-1次
{
int minn=0x3f3f3f3f