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;
    }

     

  • 相关阅读:
    Vue Router路由组件传参
    Object.defineProperty()详解
    响应状态码
    ngnix端口转发
    查看端口占用情况
    nginx的查看、启动、停止、重载命令
    nginx的几个默认路径
    pm2的一些常用命令
    为什么要学习HTML?HTML会过时吗?
    48.MySQL数据库使用(二)
  • 原文地址:https://www.cnblogs.com/duojiaming/p/11796501.html
Copyright © 2011-2022 走看看