zoukankan      html  css  js  c++  java
  • 洛谷 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("
    ")
    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 }
  • 相关阅读:
    STM32的DMA
    STM32串口接收不定长数据原理与源程序(转)
    推挽与开漏
    开关量输入检测与输出的电路设计(转)
    理解一下单片机的I2C和SPI通信
    电阻桥的作用(转)
    为什么工业上用4到20毫安电流传输数据(转)
    Keil的标题“礦ision3" 的改变(转)
    epplus动态合并列数据
    npm脚本编译代码
  • 原文地址:https://www.cnblogs.com/mrclr/p/9461556.html
Copyright © 2011-2022 走看看