P1144 最短路计数

题目描述

给出一个NN个顶点MM条边的无向无权图,顶点编号为1-N1−N。问从顶点11开始,到其他每个点的最短路有几条。

输入输出格式

输入格式:

第一行包含22个正整数N,MN,M,为图的顶点数与边数。

接下来MM行,每行22个正整数x,yx,y,表示有一条顶点xx连向顶点yy的边,请注意可能有自环与重边。

输出格式:

共NN行,每行一个非负整数,第ii行输出从顶点11到顶点ii有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans \bmod 100003ansmod100003后的结果即可。如果无法到达顶点ii则输出00。

#include <bits/stdc++.h>
#define INF 0x3fffffff
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define IOS ios::sync_with_stdio(false)
#define DEBUG cout<<endl<<"DEBUG"<<endl;
using namespace std;
int n,m,f[2000002],num[1000005],tot,a,b,vis[1000005],dis[1000005],t;
struct node{
    int next,to,w;
}edge[2000002];
void add(int u,int v,int w){
    edge[++tot].next=f[u];
    edge[tot].to=v;
    edge[tot].w=w;
    f[u]=tot;
}
void spfa(){
    fill(dis, dis + n + 10 ,INF);
    memset(vis,0,sizeof vis);
    queue<int>q;
    q.push(1);
    vis[1]=1;
    num[1]=1;
    dis[1]=0;
    while(!q.empty()){
        int u=q.front();q.pop();
        vis[u]=0;t=f[u];
        while(t){
            if (dis[u]+1<dis[edge[t].to]){//以u为中介点可以使d[edge[t].to]更优
                dis[edge[t].to]=dis[u]+1;
                num[edge[t].to]=num[u];//记得记上他的最短路数量
                if (!vis[edge[t].to]){
                    vis[edge[t].to]=1;
                    q.push(edge[t].to);
                }
            }else if(dis[u]+1==dis[edge[t].to]){//最短距离相同
                num[edge[t].to]=(num[edge[t].to]+num[u])%100003;
            }
            t=edge[t].next;
        }
    }
}
int main(void){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>a>>b;
        add(a,b,1);
        add(b,a,1);
    }
    spfa();
    for(int i=1;i<=n;i++)
        cout<<num[i]%100003<<endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值