最短路计数

题目描述

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

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例#1: 
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出样例#1: 
1
1
1
2
4

说明

1到5的最短路有4条,分别为21-2-4-52条1-3-4-5(由于4-5的边有2条)。

对于20%的数据,N ≤ 100;

对于60%的数据,N ≤ 1000

对于100%的数据,N<=1000000,M<=2000000

 

分析:

本题绝对算得上是毒瘤题。从读入开始就比较麻烦(有可能有重复的)。但是事实上本题还是最短路的一个变形,只要在每次更新后统计一下即可。

 

CODE:

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 const int MOD=100003;
 9 const int M=3000005;
10 int head[M],to[M],nxt[M],d[M],in[M],ans[M],n,m,tot;
11 int read(){
12     char c=getchar();
13     int ans=0;
14     while (c<'0'||c>'9') c=getchar();
15     while (c>='0'&&c<='9') ans=(ans<<1)+(ans<<3)+(c^48),c=getchar();
16     return ans;
17 }
18 void out(int n){
19     if (n<10){
20         putchar(n+'0');
21         return;
22     }
23     out(n/10);
24     putchar(n%10+'0');
25     return;
26 }
27 void add(int u,int v){
28     to[++tot]=v;
29     nxt[tot]=head[u];
30     head[u]=tot;
31 }
32 void spfa(){
33     memset(d,127,sizeof(d));
34     d[1]=0;in[1]=ans[1]=1;
35     queue <int> Q;
36     Q.push(1);
37     while (!Q.empty()){
38         int top=Q.front();Q.pop();in[top]=0;
39         for (int j=head[top];j!=-1;j=nxt[j])
40             if (d[top]+1<=d[to[j]]){
41                 if (d[to[j]]==d[top]+1) ans[to[j]]=(ans[to[j]]+ans[top])%MOD;
42                 else ans[to[j]]=ans[top];
43                 d[to[j]]=d[top]+1;
44                 if (!in[to[j]]) in[to[j]]=1,Q.push(to[j]);
45                 }
46         }
47     return;
48     }
49 int main(){
50     memset(head,-1,sizeof(head));
51     scanf("%d%d",&n,&m);
52     for (int i=1;i<=m;i++){
53         int u=read();
54         int v=read();
55         add(u,v);
56         add(v,u);
57     }
58     spfa();
59     for (int i=1;i<=n;i++) out(ans[i]),putchar('\n');
60     return 0;
61 }

 

posted @ 2019-07-02 13:13  Sword_Art_Online  阅读(321)  评论(0编辑  收藏  举报