zoukankan      html  css  js  c++  java
  • 最短路径 专题总结


    一.模板:

    1.dijsktra算法(矩阵):

     1 int n,cost[1005][1005],dis[1005],vis[1005],dp[1005];  
     2 void dijkstra(int st)
     3 {
     4     memset(vis,0,sizeof(vis));
     5     for(int i = 1; i<=n; i++)
     6         dis[i] = (i==st?0:INF);
     7 
     8     for(int i = 1; i<=n; i++)
     9     {
    10         int k, minn = INF;
    11         for(int j = 1; j<=n; j++)
    12             if(!vis[j]&&dis[j]<minn)
    13                 minn = dis[k=j];
    14 
    15         vis[k] = 1;
    16         for(int j = 1; j<=n; j++)
    17             if(!vis[j] && cost[k][j]!=INF)        
    18                 dis[j] = min(dis[j], dis[k] + cost[k][j]);
    19     }
    20 }
    View Code

    2.dijsktra算法(前向星):

     1 struct edge
     2 {
     3     int to, w, next;
     4 }edge[maxn*maxn];
     5 int cnt, head[maxn];
     6 
     7 void addedge(int u, int v, int w)
     8 {
     9     edge[cnt].to = v;
    10     edge[cnt].w = w;
    11     edge[cnt].next = head[u];
    12     head[u] = cnt++;
    13 }
    14 
    15 void init()
    16 {
    17     cnt = 0;
    18     memset(head, -1, sizeof(head));
    19 }
    20 
    21 int dis[maxn], vis[maxn];
    22 void dijkstra(int st)
    23 {
    24     memset(vis, 0, sizeof(vis));
    25     for(int i = 1; i<=n; i++)
    26         dis[i] = (i==st?0:INF);
    27 
    28     for(int i = 1; i<=n; i++)
    29     {
    30         int k, minn = INF;
    31         for(int j = 1; j<=n; j++)
    32             if(!vis[j] && dis[j]<minn)
    33                 minn = dis[k=j];
    34 
    35         vis[k] = 1;
    36         for(int j = head[k]; j!=-1; j = edge[j].next)
    37             if(!vis[edge[j].to])
    38                 dis[edge[j].to] = min(dis[edge[j].to], dis[k] + edge[j].w);
    39     }
    40 }
    View Code

    3.bellman-ford算法(前向星):

     1 struct edge
     2 {
     3     int u, v, w;
     4 }edge[maxn*maxn];
     5 int cnt;
     6 
     7 void addedge(int u, int v, int w)
     8 {
     9     ++cnt;
    10     edge[cnt].u = u;
    11     edge[cnt].v = v;
    12     edge[cnt].w = w;
    13 }
    14 
    15 int dis[maxn];
    16 bool bellman(int st)
    17 {
    18     for(int i = 1; i<=n; i++)
    19         dis[i] = (i==st?0:INF);
    20 
    21     for(int i = 1; i<=n-1; i++)
    22     {
    23         for(int j = 1; j<=cnt; j++)
    24         {
    25             int u = edge[j].u;
    26             int v = edge[j].v;
    27             if(dis[u]!=INF)
    28                 dis[v] = min(dis[v], dis[u]+edge[j].w);
    29         }
    30     }
    31 
    32     for(int i = 1; i<=cnt; i++)    //判断是否存在负环
    33     {
    34         int u = edge[i].u;
    35         int v = edge[i].v;
    36         if(dis[u]!=INF && dis[u]+edge[i].w<dis[v])
    37             return false;
    38     }
    39     return true;
    40 }
    View Code

    4.spfa算法(前向星):

     1 struct edge
     2 {
     3     int to, w, next;
     4 }edge[maxn*maxn];
     5 int cnt, head[maxn];
     6 
     7 void addedge(int u, int v, int w)
     8 {
     9     edge[cnt].to = v;
    10     edge[cnt].w = w;
    11     edge[cnt].next = head[u];
    12     head[u] = cnt++;
    13 }
    14 
    15 void init()
    16 {
    17     cnt = 0;
    18     memset(head, -1, sizeof(head));
    19 }
    20 
    21 int dis[maxn], times[maxn], inq[maxn];
    22 bool spfa(int st)
    23 {
    24     memset(inq, 0, sizeof(inq));
    25     memset(times, 0, sizeof(times));
    26     for(int i = 1; i<=n; i++)
    27         dis[i] = (i==st?0:INF);
    28 
    29     queue<int>Q;
    30     Q.push(st);
    31     inq[st] = 1;
    32     while(!Q.empty())
    33     {
    34         int u = Q.front();
    35         Q.pop(); inq[u] = 0;
    36         for(int i = head[u]; i!=-1; i = edge[i].next)
    37         {
    38             int v = edge[i].to;
    39             if(dis[v]>dis[u]+edge[i].w)
    40             {
    41                 dis[v] = dis[u]+edge[i].w;
    42                 if(!inq[v])
    43                 {
    44                     Q.push(v);
    45                     inq[v] = 1;
    46                     if(++times[v]>n) return false;
    47                 }
    48             }
    49         }
    50     }
    51     return true;
    52 }
    View Code

    5.floyd算法:

    1 for(int i = 1; i<=n; i++)    
    2     for(int j = 1; j<=n; j++)    
    3         scanf("%d",&dis[i][j]);    
    4 
    5 for(int k = 1; k<=n; k++)   
    6     for(int i = 1; i<=n; i++)    
    7         for(int j = 1; j<=n; j++)    
    8             dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);  
    View Code

    二.题目类型:

    1.普通最短路:

    POJ1511 Invitation Cards

    POJ3268 Silver Cow Party 

    2.最短路变形:

    POJ2253 Frogger

    POJ1797 Heavy Transportation

    CSU1808 地铁

    3.求负环或正环:

    POJ3259 Wormholes

    POJ1860 Currency Exchange

    4.传递闭包:

    POJ3660 Cow Contest

    5.差分约束:

    POJ3159 Candies 


  • 相关阅读:
    视频流媒体服务器网络硬盘录像机NVR接入/解码/转发能力解析
    流媒体服务器安装失败/程序启动错误等问题解决方案
    监控摄像头如何用作网络直播?
    数据库之单表查询
    数据库之表与表之间的关系
    数据库之完整性约束
    数据库之数据类型
    数据库之增删改查操作
    数据库之基本操作和存储引擎
    数据库之数据库基础及安装
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538618.html
Copyright © 2011-2022 走看看