zoukankan      html  css  js  c++  java
  • P1144 最短路计数 (bfs/SPFA)

    题目链接

     方法1:

      bfs

    Code:

    #include <bits/stdc++.h>
    # define LL long long
    using namespace std;
    
    const int maxn=1000000+10;
    int N,M;
    vector<int> adj[maxn];
    int res[maxn];
    int dis[maxn];
    const int mod=100003;
    
    void bfs(){
        memset(dis,-1,sizeof(dis));
        queue<int> q;
        q.push(1);
        res[1]=1;
        dis[1]=0;
        while(!q.empty()){
            int cur=q.front();
            q.pop();
            for(int i=0;i<adj[cur].size();++i){
                int v=adj[cur][i];
                if(dis[v]==-1){
                    dis[v]=1+dis[cur];
                    q.push(v);
                }
                if(dis[v]==1+dis[cur]){
                    res[v]=(res[v]+res[cur])%mod;
                }
            }
        }
    }
    
    int main(){
        scanf("%d %d", &N, &M);
        for(int i=1;i<=M;++i){
            int a,b;
            scanf("%d %d", &a, &b);
            adj[a].push_back(b);
            adj[b].push_back(a);
        }
    
        bfs();
        for(int i=1;i<=N;++i){
            printf("%d
    ", res[i]);
        }
        return 0;
    }

    方法2:

      SPFA

    Code:

    #include <bits/stdc++.h>
    # define LL long long
    using namespace std;
    
    const int maxn=1000000+10;
    int N,M;
    vector<int> adj[maxn];
    int res[maxn];
    int dis[maxn];
    const int mod=100003;
    
    void spfa(){
        memset(dis,127,sizeof(dis));
        dis[1]=0;
        res[1]=1;
        queue<int> q;
        int inqueue[maxn];
        q.push(1);
        inqueue[1]=1;
        while(!q.empty()){
            int cur=q.front();
            q.pop();
            inqueue[cur]=0;
            for(int i=0;i<adj[cur].size();++i){
                int v=adj[cur][i];
                if(dis[cur]+1<dis[v]){
                    res[v]=res[cur];
                    dis[v]=1+dis[cur];
                    if(inqueue[v]==0){
                        inqueue[v]=1;
                        q.push(v);
                    }
                }else if(dis[cur]+1==dis[v]){
                    res[v]=(res[v]+res[cur])%mod;
                }
            }
        }
    }
    
    int main(){
        scanf("%d %d", &N, &M);
        for(int i=1;i<=M;++i){
            int a,b;
            scanf("%d %d", &a, &b);
            adj[a].push_back(b);
            adj[b].push_back(a);
        }
    
        spfa();
        for(int i=1;i<=N;++i){
            printf("%d
    ", res[i]);
        }
        return 0;
    }

    以上方法只能针对无权图(权值为1)的情况,如若权值不为1,则先用spfa找最短路径,再Memo求路径条数。

    Code:

    #include <bits/stdc++.h>
    # define LL long long
    using namespace std;
    
    const int maxn=1000000+10;
    int N,M;
    vector<int> adj[maxn];
    int res[maxn];
    int dis[maxn];
    const int mod=100003;
    
    void spfa(){
        memset(dis,127,sizeof(dis));
        dis[1]=0;
        queue<int> q;
        int inqueue[maxn];
        q.push(1);
        inqueue[1]=1;
        while(!q.empty()){
            int cur=q.front();
            q.pop();
            inqueue[cur]=0;
            for(int i=0;i<adj[cur].size();++i){
                int v=adj[cur][i];
                if(dis[cur]+1<dis[v]){
                    dis[v]=1+dis[cur];
                    if(inqueue[v]==0){
                        inqueue[v]=1;
                        q.push(v);
                    }
                }
            }
        }
    }
    
    int dfs(int u){
        if(u==1){
            return res[1]=1;
        }
        if(res[u]!=-1) return res[u];
        res[u]=0;
        for(int i=0;i<adj[u].size();++i){
            int v=adj[u][i];
            if(dis[v]+1==dis[u]){
                res[u]=(res[u]+dfs(v))%mod;
            }
        }
        return res[u];
    }
    
    int main(){
        scanf("%d %d", &N, &M);
        for(int i=1;i<=M;++i){
            int a,b;
            scanf("%d %d", &a, &b);
            adj[a].push_back(b);
            adj[b].push_back(a);
        }
    
        spfa();
        memset(res,-1,sizeof(res));
        for(int i=1;i<=N;++i){
            dfs(i);
        }
    
        for(int i=1;i<=N;++i){
            printf("%d
    ", res[i]);
        }
        return 0;
    }
  • 相关阅读:
    BZOJ2034 【2009国家集训队】最大收益
    「PKUSC2018」最大前缀和
    「PKUSC2018」真实排名
    【FJOI2016】建筑师
    【FJOI2014】最短路径树问题
    【HNOI2007】紧急疏散
    【TJOI2015】线性代数
    【SDOI2017】新生舞会
    POJ2079 Triangle
    【SDOI2011】工作安排
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/12245429.html
Copyright © 2011-2022 走看看