最短路计数

给出一个 N 个顶点 M 条边的无向无权图,顶点编号为 1~N。问从顶点 1 开始,到其他每个点的最短路有几条。


对于每个点,如果有另一个点能够转移过来,那就加上转移过来的点的值

如果要更新,那就等于转移过来的点的值

注意取模,并且开大数组

我写了两个版本

ans1:(Dijkstra+堆优化)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
inline int rd(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
inline void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
    return ;
}
int n,m;
int head[100006],nxt[400006],to[400006],v[400006];
int total=0;
void add(int x,int y){
    total++;
    to[total]=y;
    nxt[total]=head[x];
    head[x]=total;
    v[total]=1;
    return ;
}
struct node{
    int u,v;
    bool operator<(const node &x) const{return u>x.u;}
};
int book[100006];
int dis[100006];
int cnt[100006];
priority_queue <node> Q;
int mod=100003;
void dij(int x){
    memset(dis,127,sizeof(dis));
    dis[x]=0;
    cnt[x]=1;
    node h;
    h.v=x,h.u=0;
    Q.push(h);
    while(!Q.empty()){
        int x=Q.top().v;
        Q.pop();
        if(book[x]) continue;
        book[x]=1;
        for(int e=head[x];e;e=nxt[e]){
            if(dis[to[e]]==dis[x]+v[e]) cnt[to[e]]=(cnt[to[e]]+cnt[x])%mod;
            if(dis[to[e]]>dis[x]+v[e]){
                dis[to[e]]=dis[x]+v[e];
                cnt[to[e]]=cnt[x];
                cnt[to[e]]%=mod;
                node k;
                k.v=to[e],k.u=dis[to[e]];
                Q.push(k);
                continue;
            }
        }
    }
    return ;
}
int main(){
    n=rd(),m=rd();
    for(int i=1;i<=m;i++){
        int x=rd(),y=rd();
        add(x,y),add(y,x);
    }
    dij(1);
    for(int i=1;i<=n;i++){
        write(cnt[i]),puts("");
    }
    return 0;
}

 

ans2:(SPFA)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
inline int rd(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
inline void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
    return ;
}
int n,m;
int head[100006],nxt[400006],to[400006],v[400006];
int total=0;
void add(int x,int y){
    total++;
    to[total]=y;
    nxt[total]=head[x];
    head[x]=total;
    return ;
}
queue <int> Q;
int book[100006];
int dis[100006];
int cnt[100006];
int mod=100003;
void spfa(int x){
    memset(dis,127,sizeof(dis));
    dis[x]=0;
    book[x]=1;
    cnt[x]=1;
    Q.push(x);
    while(!Q.empty()){
        int x=Q.front();
        Q.pop();
        book[x]=0;
        for(int e=head[x];e;e=nxt[e]){
            if(dis[to[e]]==dis[x]+1) cnt[to[e]]=(cnt[to[e]]+cnt[x])%mod;
            if(dis[to[e]]>dis[x]+1){
                dis[to[e]]=dis[x]+1;
                cnt[to[e]]=cnt[x];
                if(!book[to[e]]) book[to[e]]=1,Q.push(to[e]);
            }
        }
    }
    return ;
}
int main(){
    n=rd(),m=rd();
    for(int i=1;i<=m;i++){
        int x=rd(),y=rd();
        add(x,y),add(y,x);
    }
    spfa(1);
    for(int i=1;i<=n;i++){
        write(cnt[i]),puts("");
    }
    return 0;
}

 

posted @ 2018-10-25 16:32  Bruce--Wang  阅读(113)  评论(0编辑  收藏  举报