P1144 最短路计数
标签
进入讨论版
相关讨论
推荐题目
题目描述
给出一个NNN个顶点MMM条边的无向无权图,顶点编号为1−N1-N1−N。问从顶点111开始,到其他每个点的最短路有几条。
输入格式
第一行包含222个正整数N,MN,MN,M,为图的顶点数与边数。
接下来MMM行,每行222个正整数x,yx,yx,y,表示有一条顶点xxx连向顶点yyy的边,请注意可能有自环与重边。
输出格式
共NNN行,每行一个非负整数,第iii行输出从顶点111到顶点iii有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans mod 100003 ans \bmod 100003ansmod100003后的结果即可。如果无法到达顶点iii则输出000。
输入输出样例
输入 #1
5 7 1 2 1 3 2 4 3 4 2 3 4 5 4 5
输出 #1
1 1 1 2 4
思路
构建每个点所属的其最短路长度的组别,在跑Dijkstra的时候来更新当前点所属的组别,详见代码
CODE
1 #include <bits/stdc++.h> 2 #define dbg(x) cout << #x << "=" << x << endl 3 #define eps 1e-8 4 #define pi acos(-1.0) 5 6 using namespace std; 7 typedef long long LL; 8 9 template<class T>inline void read(T &res) 10 { 11 char c;T flag=1; 12 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 13 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 14 } 15 16 namespace _buff { 17 const size_t BUFF = 1 << 19; 18 char ibuf[BUFF], *ib = ibuf, *ie = ibuf; 19 char getc() { 20 if (ib == ie) { 21 ib = ibuf; 22 ie = ibuf + fread(ibuf, 1, BUFF, stdin); 23 } 24 return ib == ie ? -1 : *ib++; 25 } 26 } 27 28 int qread() { 29 using namespace _buff; 30 int ret = 0; 31 bool pos = true; 32 char c = getc(); 33 for (; (c < '0' || c > '9') && c != '-'; c = getc()) { 34 assert(~c); 35 } 36 if (c == '-') { 37 pos = false; 38 c = getc(); 39 } 40 for (; c >= '0' && c <= '9'; c = getc()) { 41 ret = (ret << 3) + (ret << 1) + (c ^ 48); 42 } 43 return pos ? ret : -ret; 44 } 45 46 const int maxn = 1e6 + 7; 47 const int inf = 0x3f3f3f3f; 48 const int M = 100003; 49 50 int head[maxn << 1], edge[maxn << 1], w[maxn << 1], nxt[maxn << 1]; 51 int cnt; 52 53 inline void BuildGraph (int u, int v, int c) { 54 cnt++; 55 edge[cnt] = v; 56 nxt[cnt] = head[u]; 57 w[cnt] = c; 58 head[u] = cnt; 59 } 60 61 struct node { 62 int u,v; 63 bool operator <(const node &t) const { 64 return u > t.u; 65 } 66 }; 67 68 int n,m,s,t; 69 int dis[maxn]; 70 int ans[maxn]; 71 priority_queue < node > q; 72 73 void dijkstra(int s) { 74 for (int i = 1; i <= n; ++i) { 75 dis[i] = inf; 76 } 77 dis[s] = 0; 78 node temp; 79 temp.u = 0; 80 temp.v = s; 81 q.push(temp); 82 while(!q.empty()) { 83 int u = q.top().v; 84 int d = q.top().u; 85 q.pop(); 86 if(d != dis[u]) continue; 87 for (int i = head[u]; i; i = nxt[i]) { 88 int v = edge[i]; 89 int c = w[i]; 90 if(dis[v] > dis[u] + c) { 91 dis[v] = dis[u] + c; 92 node p; 93 p.u = dis[v], p.v = v; 94 ans[v] = ans[u];///把当前点加入这条最短路长度的行列 95 q.push(p); 96 } 97 else if(dis[v] == dis[u] + c) { 98 //printf("ans[%d]:%d\n",u,ans[u]); 99 //printf("ans[%d]:%d\n",v,ans[v]); 100 ans[v] += ans[u];///当前点加上其他当前长度的行列 101 ans[v] %= M; 102 //printf("ans[%d]:%d\n",u,ans[u]); 103 //printf("ans[%d]:%d\n\n",v,ans[v]); 104 } 105 } 106 } 107 } 108 109 int main() 110 { 111 scanf("%d %d",&n, &m); 112 int a, b; 113 for (int i = 1; i <= m; ++i) { 114 scanf("%d %d",&a, &b); 115 BuildGraph(a, b, 1); 116 BuildGraph(b, a, 1); 117 } 118 ans[1] = 1; 119 dijkstra(1); 120 for ( int i = 1; i <= n; ++i ) { 121 printf("%d\n",ans[i]); 122 } 123 return 0; 124 }