zoukankan      html  css  js  c++  java
  • 最短路计数

    给出一个 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;
    }
  • 相关阅读:
    【题解】LOJ #6488 数表【FWT】
    【题解】[Comet OJ Contest #11 F] arewell【子集卷积】
    【CF757F】 Team Rocket Rises Again 【支配树】
    支配树学习笔记
    JS模拟实现题目(new debounce throwee 等)
    React生命周期
    js转义符
    CSS3中的transform转换属性
    animation动画
    flex
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/9850760.html
Copyright © 2011-2022 走看看