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

     

  • 相关阅读:
    c++入门之初话结构体
    c++学习之字符串拼接
    数组赋值问题
    c++之sizeof的用法
    MySQL 创建一个简单的成绩管理系统
    KMP算法详解
    [Leetcode] Implement strstr
    [Leetcode] Multiply strings 字符串对应数字相乘
    [Leetcode] count and say 计数和说
    [Leetcode] Roman to integer 罗马数字转成整数
  • 原文地址:https://www.cnblogs.com/duojiaming/p/11796501.html
Copyright © 2011-2022 走看看