洛谷 P1144 最短路计数

传送门:https://www.luogu.org/problemnew/show/P1144

这虽然是一道普及+的题,然而我发现我现在还没做过,这也就直接导致我今天模拟T2只杠了个暴力分……

那这道题怎么做呢?既然是最短路,那么一定要用spfa或dijkstra了,这里就讲dijkstra的做法吧,主要是这比spfa简单点,而且spfa不是那啥了吗。

众所周知,在那个所谓的什么松弛操作的时候,如果dis[u] + c[u->v] < dis[v],我们就更新dis[v],这时候从u过来的路径,就可能是到v的最短路,所以到v的最短路条数num[v] = num[u];而另一种情况是dis[u] + c[u->v] == dis[v]时,那么num[v] += num[u]了。嗯,完事了

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter printf("\n")
13 #define space printf(" ")
14 #define Mem(a) memset(a, 0, sizeof(a))
15 typedef long long ll;
16 typedef double db;
17 const int INF = 0x3f3f3f3f;
18 const int eps = 1e-8;
19 const int maxn = 1e6 + 5;
20 const int mod = 100003;
21 inline ll read()
22 {
23     ll ans = 0;
24     char ch = getchar(), last = ' ';
25     while(!isdigit(ch)) {last = ch; ch = getchar();}
26     while(isdigit(ch))
27     {
28         ans = ans * 10 + ch - '0'; ch = getchar();
29     }
30     if(last == '-') ans = -ans;
31     return ans;
32 }
33 inline void write(ll x)
34 {
35     if(x < 0) x = -x, putchar('-');
36     if(x >= 10) write(x / 10);
37     putchar(x % 10 + '0');
38 }
39 
40 int n, m;
41 vector<int> v[maxn];
42 
43 #define pr pair<int, int>
44 #define mp make_pair
45 priority_queue<pr, vector<pr>, greater<pr> > q;
46 int dis[maxn], num[maxn];
47 bool done[maxn];
48 void dijkstra(int s)
49 {
50     for(int i = 1; i <= n; ++i) dis[i] = INF;
51     dis[s] = 0; num[s] = 1;
52     q.push(mp(dis[0], s));
53     while(!q.empty())
54     {
55         int now = q.top().second; q.pop();
56         if(done[now]) continue;
57         done[now] = 1;
58         for(int i = 0; i < (int)v[now].size(); ++i)
59         {
60             if(dis[now] + 1 < dis[v[now][i]])        //此题边权都是1 
61             {
62                 dis[v[now][i]] = dis[now] + 1;
63                 num[v[now][i]] = num[now];
64                 q.push(mp(dis[v[now][i]], v[now][i]));
65             }
66             else if(dis[now] + 1 == dis[v[now][i]]) num[v[now][i]] = (num[v[now][i]] + num[now]) % mod;
67         }
68     }
69 }
70 
71 int main()
72 {
73     n = read(); m = read();
74     for(int i = 1; i <= m; ++i)
75     {
76         int x = read(), y = read();
77         v[x].push_back(y); v[y].push_back(x); 
78     }
79     dijkstra(1);
80     for(int i = 1; i <= n; ++i) {write(num[i]); enter;}
81     return 0;
82 }

猜你喜欢

转载自www.cnblogs.com/mrclr/p/9461556.html