zoukankan      html  css  js  c++  java
  • P1608 路径统计&&P1144 最短路计数

    相似的两道题

    区别在于边权

    ans数组记录方案数

    如果是第一次更新那么方案数就等于更新他的节点的方案数 

    因为他们在一条路径上

    如果此时节点的最短路等于上一个节点的最短路加上他们之间的距离

    那么此时节点的方案数就加上上一个节点的方案数

    P1144 最短路计数

    spfa

    //P1144 最短路计数
    #include<bits/stdc++.h>
    using namespace std;
    const int mod=100003;
    const int inf=987654321;
    int n,m;
    vector<int> g[4000005];
    int d[1000005],ans[1000005];
    bool v[1000005];
    inline void spfa(){
        for(int i=1;i<=n;i++){
            d[i]=inf;
        } 
        queue<int> q;
        q.push(1);
        v[1]=1;
        d[1]=0;
        ans[1]=1;
        while(q.size()){
            int x=q.front();
            q.pop();
            v[x]=0;
            int sz=g[x].size();
            for(int i=0;i<sz;i++){
                int y=g[x][i];
                if(d[y]>d[x]+1){
                    d[y]=d[x]+1;
                    ans[y]=ans[x];
                    if(!v[y]){
                        v[y]=1;
                        q.push(y);
                    }
                }else if(d[y]==d[x]+1){
                    ans[y]+=ans[x];
                    ans[y]%=mod;
                }
            }
        }
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        spfa();
        for(int i=1;i<=n;i++){
            printf("%d
    ",ans[i]);
        }
        return 0;
    }

    dij

    //P1144 最短路计数
    #include<bits/stdc++.h>
    using namespace std;
    const int mod=100003;
    const int inf=987654321;
    int n,m;
    vector<int> g[4000005];
    int d[1000005],ans[1000005];
    bool v[1000005];
    inline void dij(){
        for(int i=1;i<=n;i++){
            d[i]=inf;
        }
        priority_queue<pair<int,int> >q;
        q.push(make_pair(0,1));
        d[1]=0;
        while(q.size()){
            int x=q.top().second;
            q.pop();
            if(v[x]) continue;
            v[x]=1;
            ans[1]=1;
            int sz=g[x].size();
            for(int i=0;i<sz;i++){
                int y=g[x][i];
                if(d[y]>d[x]+1){
                    d[y]=d[x]+1;
                    ans[y]=ans[x];
                    q.push(make_pair(-d[y],y));
                }else if(d[y]==d[x]+1){
                    ans[y]+=ans[x];
                    ans[y]%=mod;
                }
            }
        }
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        dij();
        for(int i=1;i<=n;i++){
            printf("%d
    ",ans[i]);
        }
        return 0;
    }

    P1608 路径统计

    dij

    //P1608 路径统计 
    #include<bits/stdc++.h>
    using namespace std;
    const int mxm=8000005;
    const int mxn=2005;
    const int inf=987654321;
    int n,m;
    struct sc{
        int nxt,to,w;
    }g[mxm];
    int head[mxm],len;
    int d[mxn],ans[mxn];
    bool v[mxn];
    int mp[mxn][mxn];
    inline void add(int u,int v,int w){
        g[++len].to=v;
        g[len].w=w;
        g[len].nxt=head[u];
        head[u]=len;
    }
    inline void dij(){
        for(int i=1;i<=n;i++){
            d[i]=inf;
        }
        priority_queue<pair<int,int> >q;
        q.push(make_pair(0,1));
        d[1]=0;
        ans[1]=1;
        while(q.size()){
            int x=q.top().second;
            q.pop();
            if(v[x]) continue;
            v[x]=1;
            for(int i=head[x];i;i=g[i].nxt){
                int y=g[i].to,w=g[i].w;
                if(d[y]>d[x]+w){
                    d[y]=d[x]+w;
                    ans[y]=ans[x];
                    q.push(make_pair(-d[y],y));
                }else if(d[y]==d[x]+w){
                    ans[y]+=ans[x];
                }
            }
        }
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            if(!mp[x][y]){
                mp[x][y]=z;
                add(x,y,z);
            }else if(mp[x][y]>z){
                add(x,y,z);
                mp[x][y]=z;
            }
        }
        dij();
        if(d[n]==inf) puts("No answer");
        else cout<<d[n]<<" "<<ans[n];
        return 0;
    }

     

  • 相关阅读:
    SpringCloud学习笔记【七】:Eureka,Consul,Zookeeper注册中心异同点
    SpringCloud学习笔记【六】:Consul实现服务注册与发现
    Docker安装Consul
    SpringCloud学习笔记【五】:Zookeeper代替Eureka实现服务注册与发现
    Docker安装Zookeeper以及Zk常用命令
    SpringCloud学习笔记【四】:Eureka的自我保护机制
    教你如何使用docsify快速部署优美的在线文档
    SpringCloud学习笔记【三】:Actuator微服务信息完善+Discovery获取注册信息
    SpringCloud学习笔记【二】:Eureka服务注册与发现
    WPF应用中一种比较完美的权限控制设计方式
  • 原文地址:https://www.cnblogs.com/duojiaming/p/11796501.html
Copyright © 2011-2022 走看看