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

 

原文地址:https://www.cnblogs.com/duojiaming/p/11796501.html