HN OJ 13375 Flowery Trails (spfa的路径遍历)

来源:互联网 发布:淘宝商品分类在哪里 编辑:程序博客网 时间:2024/05/01 17:38

题意:就是要你求出所有最短路径上的边之和,然后把结果乘以2

思路:spfa上有一个定理:对于给定的一条边,如果从源点到该边起点的最短距离+起点到该边的最短距离+该边的权值=最短距离,那么说明该边是最短路上的边!

那么久可以干了!


AC代码:

#include <cstring>#include <cmath>#include <queue>#include <vector>#include <cstdio>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 10005;const int maxm = 600000;const int INF = 0x3f3f3f3f;int n, m;struct ee{    int to;    int nxt;    int w;}edge[maxm];int head[maxn], tol;void init(){    memset(head, -1, sizeof head );    tol = 0;}void add(int u, int v, int w){    edge[tol].to = v;    edge[tol].w = w;    edge[tol].nxt = head[u];    head[u] = tol++;}int d1[maxn], d2[maxn];bool vis[maxn];void spfa(int s, int t, int d[]){    for(int i=0; i<n; ++i) d[i] = INF;    memset(vis, false, sizeof vis );    queue<int> q;    q.push(s);    d[s] = 0;    vis[s] = true;    while(!q.empty()){        int u = q.front(); q.pop();        vis[u] = false;        for(int i=head[u]; ~i; i=edge[i].nxt){            int &v = edge[i].to;            int &cost = edge[i].w;            if(d[v] > d[u] + cost){                d[v] = d[u] + cost;                if(!vis[v]){                    vis[v] = true;                    q.push(v);                }            }        }    }}void solve(){    int s = 0, t = n-1;    spfa(s, t, d1);    spfa(t, s, d2);    ll ans = 0;    int minn = d1[t];    for(int u=0;u<n;u++)    {        for(int i=head[u];~i;i=edge[i].nxt)        {            int &v=edge[i].to;            int &cost=edge[i].w;            if(d1[u]+d2[v]+cost==minn)            {                ans+=cost;            }        }    }    printf("%I64d\n", ans*2);}int main(){    int u, v, l;    while(~scanf("%d%d", &n, &m))    {        init();        for(int i=0; i<m; ++i){            scanf("%d%d%d", &u, &v, &l);            add(u, v, l);            add(v, u, l);        }        solve();    }    return 0;}


0 0