这周主要也是做题,27道题已全部看完并写出题意,AC出三分之二左右的题目,有些题是看的答案。
通过看这些题感觉到都很类似,在数据较小时直接用Floyd算法,做出的这些题也大多数用的是Floyd算法。这些题题意无非就是一个图中两个点及权值,求最短距离,每次做这种题时都不自觉地想到并查集,也可能是上周刚练习完并查集的题目吧。
通过做题了解到一个重要思想,反向建边,P1629 邮递员送信这题就用到该思想
通过做题也熟悉了一遍优先队列(priority_queue)和队列(queue)
下面通过几道题来了解以下最短路径最小生成树
先举一个经典的例子
题意:建立一个医院,求人到医院的最短距离
题解:因为数据较小可以用Floyd算法,三重循环dis[i][k]=dis[i][j]+dis[j][k];然后再循环求dis[][]*peole[]的值,输出最小的即可
题意:每次带一件东西,运送每件物品后必须返回邮局,1是邮局,目的地2到n,求送完n-1件东西后并返回邮局的最少需要的时间。(这题用到了反向建边)
题解:先从1跑向每一个端点,一到多,然后反向建边,从多到一
void over()
{//这是一个反向建边的函数,把起点和终点互换 ,好让邮递员返回时从多到一跑最短路
for(int i=1;i<=m;i++)
{
swap(u[i],v[i]);
}
}
题意:n个城市,m条道路,两城市最多有一条道,d条道路被破坏,求修复最小道路长度使得A与B之间连接恢复。
题解:先初始化数组h为0x3f3f3f3f,然后建图保存到二维数组数组d中,同时使该两点间h为0,然后删边,使得d中两边的数值存到h中,用floyd求h的两点最小值,求出两点最短距离
P6770 [USACO05MAR]Checking an Alibi 不在场的证明
题意:F个草地,C头奶牛及奶牛所在的草地,P条边及通过该边所用的时间,求哪些奶牛能在M秒内从所在的草地到达1号位置,输出奶牛数量及其奶牛编号
题解:(这题我是看的答案做的)把时间看作边权值用Dijkstra算法
题意:在NxM图形中每一个单元格(i,j)都有一个电阻计量值Ri,雷雨云从(N,a)发出,击中(1,b)和(1,c)求最小电阻计量Rij和
题解:跑三遍最短路,分别得到a,b,c的最短路,然后枚举分叉点x(设dis ij为i到j的最短路,Ri为点i的电阻计量值,天上的点为a,地上两点为b,c,分叉点为x,那么易得最短路径为:dis a,x+dis b,x +dis c,x-2×Rx)
这周虽然是做文件中发的题目,因为很多答案中都有STL的影子,所以又看了看STL中vector,set,map,queue,priority_queue,stak的内容。
对于最短路最小生成树类问题,虽然题意看似简单,但代码方面还应该加强些,多敲多思考,灵活运用关于最小生成树和最短路径类算法,还应该学会优化代码。