zoukankan      html  css  js  c++  java
  • 最基础图论总结(Spfa与Dijkstra)

    1.Floyd

      Floyd是先枚举转接点,从而达到更新最小值的目的。到后期好像O(n^3) 像闹着玩一样,但在一些n<=100的环境下还是很好用的。。。

     1 inline void Floyd(int x){
     2     memset(dis,88,sizeof(dis));
     3     for(register int i=1,x,y;i<=m;++i){
     4         scanf("%d%d",&x,&y);
     5         scanf("%d",dis[x][y]);dis[y][x]=dis[x][y];
     6     }
     7     for(register int i=1;i<=n;++i) dis[i][i]=0;
     8     for(register int k=1;k<=n;++k){
     9         for(register int i=1;in;++i){
    10             for(register int j=1;jn;++j){
    11                 if(dis[i][k]+dis[k][j]<dis[i][j]) dis[i][j]=dis[i][k]+dis[k][j];
    12             }
    13         }
    14     }
    15 }
    Floyd

    2.Dijkstra

      Dijkstra在图论问题中主要的优点是较稳定,不会被特殊设计的测试点卡掉,还可以记录路径(噩梦。。。)下面为堆优化的代码。

     1 inline void dijkstra(int x) {
     2     priority_queue<node> q;
     3     q.push_back(node{0, s});
     4     for(register int i=1;i<=n;++i)  dis[i]=100000000;
     5     dis[x]=0;
     6     memset(judge,0,sizeof(judge));
     7     while(!q.empty()){
     8         node xx=q.top(); q.pop();
     9         int to=xx.to;
    10         if(judge[to]) continue;//如果这个点已经被提出过了,直接抛弃 (适用于那种松弛之后重复放入队列的点)
    11         judge[to]=true;
    12         for(register int i=0;i<q[to].size();++i){
    13             Edge& e = edges(q[to][i]);
    14             if(e.dist+dis[to]<dis[e.to]&&dis[to]<100000000) {
    15                 dis[e.to]=e.dist+dis[to];
    16                 p[e.to]=G[to][i]; //记录路径
    17                 q.push_back(Edge(dis[e.to], e.to));//把松弛过后点的d值重新放入队列
    18             }
    19         }
    20     }
    21 }
    Dijkstra

    3.Spfa

      Spfa是笔者比较青睐的算法。Spfa可以在压队的过程中判断是否存在环,还可以处理负环。

     1 inline void Spfa(int x){
     2     queue<int> q;
     3     memset(dis,88,sizeof(dis));
     4     memset(judge,0,sizeof(judge);
     5     dis[x]=0;
     6     q.push(x);
     7     while(q.size()){
     8         int xx=q.front(); q.pop;
     9         for(register int i=first[xx];i;i=a[i].next){
    10             int to=a[i].to;
    11             if(dis[to]+a[i].w<dis[xx]){
    12                 dis[xx]=dis[to]+a[i].w;
    13                 if(!judge[to]){
    14                     q.push(to); judge[to]=1;
    15                     nums[y]++;//记录加入次数 
    16                     if(nums[y]>n)   return 0;
    17                     //如果这个点加入超过n次,说明存在负圈,直接返回 
    18                 }
    19             }
    20         }
    21     }
    22 }
    Spfa
    越努力 越幸运
  • 相关阅读:
    Mosaic 前端微服务框架
    使用skipper 扩展fabio 的路由&&http proxy 功能
    Introducing Makisu: Uber’s Fast, Reliable Docker Image Builder for Apache Mesos and Kubernetes
    lua-resty-shell 多任务执行
    openresty 使用lua-resty-shell 执行shell 脚本
    ncm 让跨项目配置一致性简单的工具
    lapis 项目添加prometheus 监控集成grafana
    使用prometheus+ grafana+nginx-module-vts 模块监控openresty
    两天快速开发一个自己的微信小程序
    笔记本如何查看mac地址
  • 原文地址:https://www.cnblogs.com/OI-zzyy/p/11110543.html
Copyright © 2011-2022 走看看