#include<iostream> #include<cstdio> #include<cstring> #define int long long
usingnamespace std;
int l, r, x, y; int f[30][2][2][30]; int cnt[40], len;
intdfs(int step, int ze, int lim, int last) { if (f[step][ze][lim][last]) return f[step][ze][lim][last]; if (step == 0) return1; int tmp = 0; int maxx = lim ? cnt[step] : 9; for (int i = 0; i <= maxx; ++i) { if (last == x && i == y) continue; tmp += dfs(step - 1, ze & (i == 0), lim & (i == maxx), (ze & (i == 0)) ? 20 : i); } f[step][ze][lim][last] = tmp; return tmp; }
intdp(int x) { memset(f, 0, sizeof(f)); len = 0; while (x) { cnt[++len] = x % 10; x /= 10; } returndfs(len, 1, 1, 20); }
#include<iostream> #include<cstdio> #include<vector> #include<queue> #include<cstring> #include<map> #include<bitset> #include<unordered_map> #define ll long long #define int long long #pragma GCC optimize(3) usingnamespace std;
constint N = 2e6 + 10; int n, m; int head[N], nxt[N], to[N]; ll len[N], e_tot; ll f[N], g[N]; ll dis[N]; int vis[N]; int siz[N]; int imp[N], tot, isimp[N]; unordered_map<int, int> mapp[N]; vector<int> ne[N]; vector<int> stk; int in[N]; priority_queue<pair<ll, int> > q; ll ans; bitset<30010> S[30010];
voidadd(int x, int y, ll z) { nxt[++e_tot] = head[x], head[x] = e_tot, to[e_tot] = y, len[e_tot] = z; }
voiddij(int s) { memset(dis, 0x3f, sizeof(dis)); memset(vis, 0, sizeof(vis)); dis[s] = 0; q.push(make_pair(0, s)); while (q.size()) { int u = q.top().second; q.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; i; i = nxt[i]) { int v = to[i]; //if (vis[v]) continue; if (dis[v] > dis[u] + len[i]) { dis[v] = dis[u] + len[i]; q.push(make_pair(-dis[v], v)); } } } }
signedmain() { scanf("%lld%lld", &n, &m); for (int i = 1; i <= m; ++i) { int a, b; ll c; scanf("%lld%lld%lld", &a, &b, &c); add(a, b, c), add(b, a, c); } dij(1); for (int i = 1; i <= n; ++i) { f[i] = dis[i]; } dij(n); for (int i = 1; i <= n; ++i) { g[i] = dis[i]; } for (int i = 1; i <= n; ++i) { if (f[i] + g[i] == f[n]) { isimp[i] = 1; imp[++tot] = i; } } for (int i = 1; i <= tot; ++i) { int u = imp[i]; for (int i = head[u]; i; i = nxt[i]) { int v = to[i]; if (isimp[v] && f[u] < f[v] && !mapp[u][v]) ne[u].push_back(v), mapp[u][v] = 1, ++in[v]; } } for (int i = 1; i <= tot; ++i) { int u = imp[i]; if (!in[u]) stk.push_back(u); } for (int i = 1; i <= tot; ++i) { int u = stk[i - 1]; S[u][u] = 1; for (vector<int> :: iterator it = ne[u].begin(); it != ne[u].end(); ++it) { int v = *it; --in[v]; S[v] |= S[u]; if (!in[v]) { stk.push_back(v); } } } for (int i = 1; i <= tot; ++i) { int u = imp[i]; ans = ans + 1ll * (S[u].count() - 1); } cout << ans << endl; return0; }