• 【算法3.7】spfa(完结)


    目录

    一、851 spfa求最短路

    二、852 spfa判断负环


    1. int spfa()
    2. {
    3. memset(dist,0x3f,sizeof dist);
    4. dist[1]=0;
    5. queue<int>q;
    6. q.push(1);
    7. st[1]=true;
    8. while(q.size())
    9. {
    10. auto t=q.front();
    11. q.pop();
    12. st[t]=false;
    13. for(int i=h[t];i!=-1;i=ne[i])
    14. {
    15. int j=e[i];
    16. if(dist[j] > dist[t]+w[i])
    17. {
    18. dist[j]=dist[t]+w[i];
    19. if(!st[j])
    20. {
    21. q.push(j);
    22. st[j]=true;
    23. }
    24. }
    25. }
    26. }
    27. return dist[n];
    28. }

    一、851 spfa求最短路

    活动 - AcWing

    给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数

    请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 impossible

    数据保证不存在负权回路。

    输入格式

    第一行包含整数 n 和 m。

    接下来 m 行每行包含三个整数 x,y,z 表示存在一条从点 x 到点 y 的有向边,边长为 z。

    输出格式

    输出一个整数,表示 1 号点到 n 号点的最短距离。

    如果路径不存在,则输出 impossible

    数据范围

    1≤n,m≤105
    图中涉及边长绝对值均不超过 10000

    输入样例:

    1. 3 3
    2. 1 2 5
    3. 2 3 -3
    4. 1 3 4

    输出样例:

    2
    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int N=1e6+10;
    7. int n,m;
    8. int h[N],w[N],e[N],ne[N],idx; //稀疏图用邻接表存
    9. int dist[N]; //用于存储每个点到起点的最短距离
    10. bool st[N];
    11. void add(int a,int b,int c)
    12. {
    13. e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
    14. }
    15. int spfa()
    16. {
    17. memset(dist,0x3f,sizeof dist);
    18. dist[1]=0;
    19. queue<int>q;
    20. q.push(1);
    21. st[1]=true;
    22. while(q.size())
    23. {
    24. auto t=q.front();
    25. q.pop();
    26. st[t]=false;
    27. for(int i=h[t];i!=-1;i=ne[i])
    28. {
    29. int j=e[i];
    30. if(dist[j] > dist[t]+w[i])
    31. {
    32. dist[j]=dist[t]+w[i];
    33. if(!st[j])
    34. {
    35. q.push(j);
    36. st[j]=true;
    37. }
    38. }
    39. }
    40. }
    41. return dist[n];
    42. }
    43. int main()
    44. {
    45. cin>>n>>m;
    46. memset(h,-1,sizeof h);
    47. while(m--)
    48. {
    49. int a,b,c;
    50. cin>>a>>b>>c;
    51. add(a,b,c);
    52. }
    53. if(spfa()==0x3f3f3f3f) puts("impossible");
    54. else cout<<spfa();
    55. return 0;
    56. }

     

     

    二、852 spfa判断负环

    活动 - AcWing

    给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数

    请你判断图中是否存在负权回路。

    输入格式

    第一行包含整数 n 和 m。

    接下来 mm 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。

    输出格式

    如果图中存在负权回路,则输出 Yes,否则输出 No

    数据范围

    1≤n≤2000
    1≤m≤10000
    图中涉及边长绝对值均不超过 10000

    输入样例:

    1. 3 3
    2. 1 2 -1
    3. 2 3 4
    4. 3 1 -4

    输出样例:

    Yes
    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int N=1e5+10;
    6. int dist[N],cnt[N];//cnt数组用于记录当前该最短路的边数
    7. int h[N],e[N],ne[N],w[N],idx;
    8. int n,m;
    9. bool st[N];
    10. void add(int a,int b,int c)
    11. {
    12. e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
    13. }
    14. bool spfa()
    15. {
    16. //这里不需要初始化dist数组原因是 如果存在负环 则dist不管初始化为多少 都会被更新
    17. queue<int>q;
    18. for(int i=1;i<=n;i++) //不仅仅是1了 因为点1可能到不了有负环的点 因此把所有点都加入队列
    19. {
    20. q.push(i);
    21. st[i]=true;
    22. }
    23. while(q.size())
    24. {
    25. int t=q.front();
    26. q.pop();
    27. st[t]=false;
    28. for(int i=h[t];i!=-1;i=ne[i])
    29. {
    30. int j=e[i];
    31. if(dist[j]>dist[t]+w[i])
    32. {
    33. dist[j]=dist[t]+w[i];
    34. cnt[j]=cnt[t]+1;
    35. if(cnt[j]>=n) return true; //如果cnt[x]>=n说明至少经过n条边 也就是n+1个点 则一定存在负环
    36. if(!st[j])
    37. {
    38. q.push(j);
    39. st[j]=true;
    40. }
    41. }
    42. }
    43. }
    44. return false;
    45. }
    46. int main()
    47. {
    48. memset(h,-1,sizeof h);
    49. cin>>n>>m;
    50. for(int i=0;i
    51. {
    52. int a,b,w;
    53. cin>>a>>b>>w;
    54. add(a,b,w);
    55. }
    56. if(spfa()) puts("Yes");
    57. else puts("No");
    58. return 0;
    59. }

     

  • 相关阅读:
    算法 杨辉三角求解 java打印杨辉三角 多路递归打印杨辉三角 递归优化杨辉三角 记忆法优化递归 帕斯卡三角形 算法(十二)
    vue3.0+ts+element ui中如何使用svg图片
    活性基团功能化PEG纳米金包Fe3O4磁纳米颗粒
    Nacos源码分析专题(一)-环境准备
    MySQL主从复制原理和使用
    时间复杂度和空间复杂度
    MASM 64汇编
    暴力递归转动态规划(十七)
    不止于Kubernetes,开发人员应着眼于更多适合云原生应用的范式
    Linux下应用程序调试
  • 原文地址:https://blog.csdn.net/weixin_61639349/article/details/126430139