模板整理: 图论---最短路

来源:互联网 发布:工业机器人技术编程 编辑:程序博客网 时间:2024/06/06 04:38


最短路……基础但重要……
主要有floyd,dijkstra,SPFA这种,
看数据范围的。
floyd还可以用来求传递闭包,也就是连通性的问题。

最短路问题:给出一张图,求s~t的最短路。
1.floyd算法。
使用它的时候一般都是用邻接矩阵计算了……

//dis[i][j]一开始的初值://若输入的边里有(i,j),则dis[i][j]为其权值//不然dis[i][j]=INFfor (int k=1;k<=n;k++)    for (int i=1;i<=n;i++)        for (int j=1;j<=n;j++)            dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);


……注意了有个问题就是如果初始化的值过大,
然后dis[i][k]和dis[k][j]都为INF,
INF过大……两个相加……就会爆辣!
所以初值要么不要太大,要么更新的时候判断一下。

2.dijkstra算法+堆优化
……最稳的最短路算法了。
优化一下找最小dis的过程,用堆维护,
C++STL轻松= v =
如果堆加上映射,也就是增加删除操作会更快。
多用用它吧!

//head,E都是边表(链表)的部分……//stl大法好(可怜P党QAQ)struct Heap{int num,val;};priority_queue<Heap,vector<Heap> >Q;bool operator <(Heap x,Heap y){return x.val>y.val;}bool operator >(Heap x,Heap y){return x.val<y.val;}void dijkstra(int s,int t){    memset(vis,0,sizeof(vis));    memset(dist,100,sizeof(dist));    dist[s]=0;    Q.push((Heap){s,0});    while ((!Q.empty())){        Heap mi=Q.top();Q.pop();        if (vis[mi.num]) continue;        vis[mi.num]=1;        for (int j=head[mi.num];j;j=E[j].next){            int q=E[j].to;            if (vis[q]) continue;            if (E[j].val+mi.val<dist[q]){                dist[q]=E[j].val+mi.val;                Q.push((Heap){q,dist[q]});            }        }    }}


3.SPFA算法
性价比很高,好写好记而且一般都挺快,实质是BE优化。
菊花图(就是那种发散的图),或者网格图之类的会被卡。
思路……就是暴力广搜松弛啦,好像O(m)左右(一般情况)

//这里用了循环队列,循环长度是Mint SPFA(int sta,int end){    memset(vis,0,sizeof(vis));    memset(dis,60,sizeof(dis));    int h=0,tail=1;    Q[0]=sta; dis[sta]=0;    while (h!=tail){        int u=Q[h];        h=(h+1)%M;        vis[u]=0;        for (int i=head[u];i;i=E[i].next)            if (dis[u]+E[i].val<dis[E[i].to]){                dis[E[i].to]=dis[u]+E[i].val;                if (!vis[E[i].to]){                    vis[E[i].to]=1;                     Q[tail]=E[i].to;                    tail=(tail+1)%M;                }            }    }    return dis[end];}


注意了,以上的模板里面有初始化,
因为我懒(划掉(lll¬ω¬))所以用了memset,
实际问题中要注意初始化初值的大小也是很重要的!

原创粉丝点击