最短路计数

C. 最短路计数(shortest) Problem 4453  ] Discussion ]


Description

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

Input

第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行两个正整数x,y,表示有一条顶点x连向顶点y的边,**请注意可能有自环与重边**。

Output

包括NN行,每行一个**非负整数**,第i行输出**从顶点1到顶点ii有多少条不同的最短路**,由于答案有可能会很大,你只需要输出**mod 100003**后的结果即可。如果无法到达顶点ii则输出0。

Samples

Input Copy
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
Output
1
1
1
2
4

Hint

样例解释:1到5的最短路有4条,分别为2条1-2-4-5和2条1-3-4-5(由于4-5的边有2条)。 
数据说明:

  • 对于20%的数据,N100
  • 对于60%的数据,N1000
  • 对于100%的数据,N100000N≤100000,

Source

石光中学 2018泉州集训普及组day5
 
 
最短路计数
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstring>
#include<cstdio>
#include<iostream>
#include<queue> 
#include<algorithm>
using namespace std;
typedef long long ll;
template <typename Tp>
void read(Tp &x){//read(n);
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')){
        ch=getchar();
    }
    if(ch=='-'){
        fh=-1;ch=getchar();
    }else fh=1;
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
    }
    x*=fh;
}
inline char read1()//字符串读入挂
{
    register char ch=getchar();
    while(ch<'A'||ch>'M')ch=getchar();
    return ch; 
}
const int maxn=1e6+100;
const int mod=100003; 
int head[maxn],d[maxn],ans[maxn];
int vis[maxn];
int n,m,s,t,W;
struct node{
    int to;
    int next;
    int w;
}edge[maxn];
int cnt=0;
void add(int u,int v,int w){
    edge[++cnt].w=w;
    edge[cnt].to=v;
    edge[cnt].next=head[u];
    head[u]=cnt;
}
void spfa(){
    memset(d,0x3f3f3f,sizeof d);
    queue<int>q;
    d[s]=0;//起点 
    vis[s]=1;
    ans[s]=1;// 本身为1个最短路 
    q.push(s);
    while(q.size()){
        int x=q.front();q.pop();
        vis[x]=0;
        for(int i=head[x];i;i=edge[i].next){
            int y=edge[i].to;
            if(d[y]>d[x]+edge[i].w){//如果满足u到v的距离比原本到v的距离小,则更新
                d[y]=d[x]+edge[i].w;
                ans[y]=ans[x];// x点和y点在一条路上,所以y的最短路个数等于x的最短路个数
                if(!vis[y]){
                    q.push(y);
                    vis[y]=1;
                }
            }
            else if(d[y]==d[x]+edge[i].w){
                ans[y]+=ans[x];// 该点最短路个数为y最短路个数+x最短路个数
                ans[y]%=mod;
            }
        } 
    }
    
}
void inint(){
    cin>>n>>m;
    s=1;//起点 
    for(int i=1;i<=m;i++){
        int a,b;
        read(a),read(b);
        add(a,b,1);
        add(b,a,1);
    }
}
int main(){
    inint();
    spfa();
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<endl;
    } 
    
}

 

posted @ 2021-01-20 23:57  哎呦哎(iui)  阅读(73)  评论(0编辑  收藏  举报