1. 程式人生 > >P1608 路徑統計

P1608 路徑統計

真正的最短路計數問題

這道題就是傳說中的最短路計數問題了。

其實最短路計數就是在最短路演算法上面新增兩句話就完事了。

一句是在判斷有道路與當前最短路一樣長的時候,答案會變多。

一句是在更新最短路的時候,答案會變成從那個點開始的最短路。

所以就沒有問題了?

這道題不僅有重邊,還可能後面給你更小的邊!

解決方法有兩個:

  1. 乖乖用鄰接矩陣,寫一下基於矩陣的dijkstra。

  2. 用個鄰接矩陣來判斷下邊的關係,看看有相同起點終點的邊是否需要加進來。再換成鄰接表跑堆優化的dijkstra。

我用的是第二種。我不會寫矩陣的演算法除了floyd。

程式碼:

#include<cstdio>
#include<cstring>
#include<queue>
const int maxn = 2005;
struct Edges
{
    int next, to, weight;
} e[4000005];
int b[maxn][maxn];
int head[maxn], tot;
int dist[maxn];
int cnt[maxn];
int n, m;
struct Heapnodes
{
    int d, u;
    bool operator < (const Heapnodes &rhs) const
    {
        return d > rhs.d;
    }
};

int read()
{
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0', ch = getchar();
    return s * ans;
}
void link(int u, int v, int w)
{
    e[++tot] = (Edges){head[u], v, w};
    head[u] = tot;
}
void dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    std::priority_queue<Heapnodes> heap;
    dist[1] = 0; heap.push((Heapnodes){dist[1], 1});
    cnt[1] = 1;
    while(!heap.empty())
    {
        Heapnodes x = heap.top(); heap.pop();
        int d = x.d, u = x.u;
        if(d != dist[u]) continue;
        for(int i = head[u]; i; i = e[i].next)
        {
            int v = e[i].to;
            if(dist[u] + e[i].weight == dist[v]) cnt[v] += cnt[u];
            if(dist[u] + e[i].weight < dist[v])
            {
                dist[v] = dist[u] + e[i].weight;
                heap.push((Heapnodes){dist[v], v});
                cnt[v] = cnt[u];
            }
        }
    }
}
int main()
{
    memset(b, 0x3f, sizeof b);
    n = read(), m = read();
    while(m--)
    {
        int u = read(), v = read(), w = read();
        if(b[u][v] > w)
        {
            link(u, v, w);
            b[u][v] = w;
        }
    }
    dijkstra();
    if(dist[n] != 0x3f3f3f3f) printf("%d %d\n", dist[n], cnt[n]);
    else printf("No answer\n");
    return 0;
}