最近看了下算法书,对编程懂了点皮毛,总结下一些常用算法,留着以后用。
一、最短距离与最长距离问题
这种问题一般都是从单源点到其他点最短距离或者最长距离,求这类问题采用算法一般是Dijkstra算法。
解决这类问题通常会碰到几个难点:
1)如何表示两点之间的权重?一般情况下可以采用两种办法表两点之间权重,即使二维数组和邻接表。
二维数组一般都是根据图点个数N,然后开辟一个N*N的二维数组a[N][N],用a[i][j]表示从i点到j点的权重。
假设m为边的个数,即有:
for(int k=0;k<m;k++){
cin>>i>>j>>w;//输入两点以及他们之间权重
a[i][j] = w;
//a[i][j] = a[j][i] =w ; 如果是无向图;
}
二维数组一般都比较浪费内存,特别是点比较多,而边比较少时,这就需要更加有效的办法。邻接表可以很好解决这类问题,其原理就是为了每个点建立一个链表,每个 点都有表头,然后根据这个就可以找出该点与其他连接点,以及他们之间权重,其巧妙之处就是如何根据这个找到下个点。
struct Node{
int u;//开始点;
int v;//结束点;
int w;//权重
int next;//可以找到下个连接点
}snode[1000];
假设有个这样图:1 点到 2点权重为10 ; 1 点到3点权重为20;
snode[0].u = 1; snode[0].v =2 ;snode[0].w = 10 ;snode[0] .next= -1(表示表结束了,没有其他连接点了)。
snode[1].u = 1; snode[0].v = 3;snode[0].w = 20;snode[1] .next= 0(根据这个0就可以找snode[0],然后就可以找到下个连接点)。
其程序如下:
int head[1000];int t =0;
memset(head,-1,sizeof(head));
for(int k=0;k<m;k++){
cin>>i>>j>>w;
snode[k].u = i
snode[k].v = j;
snode[k].w = w;
snode[k].next = head[i];(关键是这一步,其意思可以简单理解将下个snode下标赋给next,这个就可以根据next找到下个);
head[i] = t;
t++;
}
2)上面讲述基于图点都是用数字表示,1,2,3,4,如果图点是给出名字(字符串)时,即要将他们转换成数字,其转换办法用到c++stl中map。
首先定义这样map<string,int > m;
map中字符串表示地名,整形表示对应下标。
假设给出这个图:xing到dong 权重10;huang到xing权重;
for(int k=0;k<m;k++){
}