题意:
定义一条路径的权值为路径上所有边的编号直接相连所得到的十进制数字的大小
求1到每个点的最短路mod 1e9+7
n,m<=100000。
题解:
对于一个点来说,他肯定跑位数最少,其次就是字典序最小,可以把边权拆开,然后跑bfs就会满足位数最少,那么字典序最小,就在bfs的过程中满足,然后利用分层图的思想。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 1e6 + 10; 6 const int mod = 1e9 + 7; 7 inline int read() 8 { 9 char ch = getchar();int x = 0, f = 1; 10 while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();} 11 while(ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) - '0' + ch; ch = getchar();} 12 return x * f; 13 } 14 15 int n, m, cnt; 16 vector<int>g[N][10], q[N]; 17 int c[N]; 18 int st[N]; 19 int ans[N]; 20 int vis[N]; 21 22 void add(int x, int y, int z) 23 { 24 int res = 0; 25 while(z) c[++ res] = z % 10, z /= 10; 26 int last = x, now; 27 for (int i = res; i >= 1; i --) 28 { 29 if(i != 1) now = ++ cnt; 30 else now = y; 31 g[last][c[i]].push_back(now); 32 last = now; 33 } 34 last = y; 35 for (int i = res; i >= 1; i --) 36 { 37 if(i != 1) now = ++ cnt; 38 else now = x; 39 g[last][c[i]].push_back(now); 40 last = now; 41 } 42 } 43 44 45 int main() 46 { 47 n = read(), m = read(); 48 cnt = n; 49 for (int i = 1; i <= m; i ++) 50 { 51 int x = read(), y = read(); 52 add(x, y, i); 53 } 54 int t = 1; 55 q[1].push_back(1); 56 st[1] = 1; 57 for (int i = 1; i <= t; i ++) 58 { 59 for (int j = 0; j <= 9; j ++) 60 { 61 bool flag =false; 62 for (int k = 0; k < q[i].size(); k ++) 63 { 64 int tt = q[i][k]; 65 66 for (auto w : g[tt][j]) 67 { 68 if(!st[w]) 69 { 70 ans[w] = (1ll * ans[tt] * 10% mod + j) % mod; 71 flag = true; 72 st[w] = 1; 73 q[t + 1].push_back(w); 74 } 75 } 76 } 77 if(flag) ++ t; 78 } 79 } 80 for (int i = 2; i <= n; i ++) 81 { 82 printf("%d ", ans[i]); 83 } 84 }