• 洛谷P1608路径统计


    前言

    关于本题,我由于被坑了一晚上...所以甚至发了个讨论版(点击查看)

    由于SPFA多次入队的特殊性,导致需要一些特殊操作(本题类似P1144最短路计数,但那个题不进行spfa特殊操作能过)

    更改一处:此处对上文进行更改,由于P1144边权都为1,所以不存在多次入队的情况,所以实际上没有问题,是我考虑不周!

    本题坑点(做法):

    • 去重边(读入时)
    • dp数组每次清0,保证不会重复计算路径数(若用dijk,则没这个问题),不过这样只能保证dp[n]的正确性,其余的dp数组最后都为0了
    • 只要dp数组被更改过就要入队

    代码

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=2005;
      4 const int maxm=2e6+10;
      5 const int mod =100003;
      6 int head[maxm],dis[maxn],vis[maxn],dp[maxn];
      7 int cnt;
      8 /*
      9 #define pr pair<int,int>
     10 #define mp make_pair
     11 priority_queue<pr,vector<pr>,greater<pr> > q;
     12 */
     13 int v[maxn][maxn];
     14 int n,m;
     15 queue<int> q;
     16 struct edge
     17 {
     18     int to,nxt,w;
     19 }a[maxm];
     20 void add(int x,int y,int w)
     21 {
     22     a[++cnt].nxt=head[x];
     23     head[x]=cnt;
     24     a[cnt].to=y;
     25     a[cnt].w=w;
     26 }
     27 bool flag;
     28 void SPFA()
     29 {
     30     memset(dis,0x3f,sizeof(dis));
     31 //    memset(vis,0,sizeof(vis));//注意清空 
     32 //    for(int i=1;i<=n;i++)
     33 //        dis[i]=0x7fffffff;
     34     dis[1]=0;
     35     dp[1]=1;
     36     vis[1]=1;
     37     q.push(1);
     38     while(!q.empty())
     39     {
     40         int u = q.front();
     41         q.pop();
     42         vis[u]=0;
     43         if(u==n) {flag=1;continue;}
     44         for(int i=head[u];i;i=a[i].nxt)
     45         {
     46             int v=a[i].to;
     47             if(dis[v]>dis[u]+a[i].w)
     48             {
     49                 dis[v]=dis[u]+a[i].w;
     50                 dp[v]=dp[u];
     51             //    if(!vis[v]) {q.push(v);vis[v]=1;}
     52             }
     53             else if(dis[v]==dis[u]+a[i].w)
     54             {
     55                 dp[v]+=dp[u];
     56             }
     57             if(dp[v]&&!vis[v]) {q.push(v);vis[v]=1;}
     58         }
     59         dp[u]=0;
     60     }
     61 }
     62 int main()
     63 {
     64     scanf("%d%d",&n,&m);
     65     int x,y,w;
     66     for(int i=1;i<=m;i++)
     67     {
     68         scanf("%d%d%d",&x,&y,&w);
     69         if(v[x][y]==0)
     70         {            
     71             add(x,y,w);
     72             v[x][y]=w;
     73             
     74         }
     75         else if(v[x][y]>w)
     76         {
     77             int j;
     78             for (j=head[x];j&&a[j].to!=y;j=a[j].nxt) ;
     79             a[j].w=w;
     80             v[x][y]=w;
     81         }
     82 
     83     }
     84     SPFA();
     85     if(!flag) printf("No answer");
     86     else
     87     {
     88         printf("%d %d\n",dis[n],dp[n]);
     89     }
     90 //    for(int i=1;i<=n;i++)
     91 //        printf("%d ",dp[i]);
     92 /*
     93 5 5
     94 1 2 1
     95 2 3 1
     96 3 4 1
     97 4 5 1
     98 1 4 3
     99 输出:4 2 
    100 */
    101     return 0;
    102 }

    吐槽

    关于SPFA:它死了!

  • 相关阅读:
    2021.01.28 Rating赛
    2021.01.23 Rating赛补题报告
    Codeforces Round #104 (Div.2)补题报告
    Codeforces Beta Round #73(Div2)补题报告
    11.28天梯赛补题报告
    11月22日天梯训练补题报告
    11.14补题报告
    CCNA笔记
    Centos上安装mysql配置并授权远程连接部署项目
    web容器(03):Nginx配置负载均衡
  • 原文地址:https://www.cnblogs.com/conprour/p/14373232.html
Copyright © 2020-2023  润新知