最短路计数

最短路计数在求最短路时经常会用到

https://www.luogu.org/problemnew/show/P1144

上代码

 1 #include<bits/stdc++.h>
 2 #define read read()
 3 using namespace std;
 4 const int N=1e6+5,mod=1e5+3;
 5 int n,m,size;
 6 int head[N],dis[N],vis[N],ans[N];
 7 
 8 inline int read
 9 {
10     int x=0;char ch=getchar();
11     while(ch<'0'||ch>'9')ch=getchar();
12     while(ch>='0' && ch<='9') {x=10*x+(ch-'0'); ch=getchar();}
13     return x;
14 }
15 
16 struct edge{
17     int v,next;
18 }e[N<<1];
19 
20 inline void add(int u,int v)
21 {
22     e[++size].v=v;
23     e[size].next=head[u];
24     head[u]=size;
25 }
26 
27 inline void readdata()
28 {
29     n=read; m=read;
30     int u,v;
31     for(int i=1;i<=m;i++)
32     {
33         u=read; v=read;
34         add(u,v);
35         add(v,u);
36     }
37 }
38 
39 queue<int>q;
40 inline void spfa()
41 {    
42     dis[1]=0; q.push(1); vis[1]=1; ans[1]=1;
43     while(!q.empty())
44     {
45         int u=q.front(); q.pop(); vis[u]=0;
46         for(int i=head[u];i;i=e[i].next)
47         {
48             int v=e[i].v;
49             if(dis[v]>dis[u]+1)
50             {
51                 dis[v]=dis[u]+1;
52                 ans[v]=ans[u];
53                 if(!vis[v])
54                 {
55                     q.push(v); vis[v]=1;
56                 }
57             }
58             else if(dis[v]==dis[u]+1)
59             {
60                 ans[v]+=ans[u];
61                 ans[v]%=mod;
62             }
63         }
64     }
65 }
66 
67 inline void work()
68 {
69     memset(dis,0x3f,sizeof(dis));    
70     spfa();
71     for(int i=1;i<=n;i++)
72     {
73         printf("%d
",ans[i]);
74     }
75 }
76 
77 int main()
78 {
79     readdata();
80     work();
81     return 0;
82 }

核心只有四行

1 if(dis[v] > dis[u] + 1)
2     ans[v] = ans[u];
3 else if(dis[v]==dis[u] + 1)
4     ans[v] += ans[u];     

Q:这么写为什么是对的呢?

A:如果能通过松弛操作松弛,则说明u,v在同一最短路上;

  如果不能但同样是最短路,就加进来;

另附一道水题

https://www.luogu.org/problemnew/show/P1608

原文地址:https://www.cnblogs.com/mzg1805/p/10305870.html