Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define pb emplace_back
- using namespace std;
- using ll = long long;
- #ifdef KEV
- #define DE(i, e) cerr << #i << ' ' << i << e
- void debug(auto L, auto R) { while (L < R) cerr << *L << " \n"[L+1==R], ++L; }
- #else
- #define DE(...) 0
- void debug(...) {}
- #endif
- const int maxn = 2510, p = 1e9+7;
- #define int ll
- int dp[maxn], n, cnt[maxn][maxn], x, y, m, k, tmp[maxn];
- vector<pair<int,int>> edge[maxn];
- int g[maxn], sz[maxn];
- void init() {
- for (int i = 1;i <= n;++i)
- g[i] = i, sz[i] = 1;
- }
- int find(int i) { return g[i] == i ? i : g[i] = find(g[i]); }
- void merge(int a, int b) {
- a = find(a), b = find(b);
- if (a == b) return;
- if (sz[a] < sz[b]) swap(a, b);
- sz[a] += sz[b];
- g[b] = a;
- }
- void bfs(int s) {
- static int dis[maxn];
- fill(dis, dis+n+1, -1);
- dis[s] = 0;
- queue<int> togo;
- togo.push(s);
- int G = find(s);
- while (togo.size()) {
- int now = togo.front();
- togo.pop();
- if (now != s)
- ++cnt[ G ][ min(y, dis[now]) ];
- for (auto E : edge[now]) {
- int u, w;
- tie(u, w) = E;
- if (dis[u] == -1) {
- dis[u] = dis[now] + w;
- togo.push(u);
- }
- }
- }
- }
- int mul(ll a, ll b) { return a * b % p; }
- //void add(int &v, ll val) { v = (v + val) % p; }
- void add(ll &v, ll val) { v = (v + val) % p; }
- ll inv(int v) { return v == 1 ? 1 : (p - p / v) * inv(p % v) % p; }
- ll solve() {
- dp[0] = 1;
- ll all = 0, way = 1;
- int *dp = ::dp, *ne = ::tmp;
- for (int i = 1;i <= n;++i) if (i == find(i)) {
- ll tmp = 0, cy = 0;
- for (int j = 0;j <= y;++j) if(cnt[i][j]) {
- add(tmp, (ll)(j+x) * cnt[i][j] % p * way);
- cy += cnt[i][j];
- }
- way = mul(way, cy);
- all = mul(all, cy);
- add(all, tmp);
- fill(ne, ne+y, 0);
- vector<pair<int,int>> dis;
- for (int j = 0;j < y;++j)
- if (cnt[i][j]) dis.pb(j + x, cnt[i][j]);
- // for (auto [len, way] : dis)
- // DE(len, ' '), DE(way, '\n');
- for (int j = y-1;j >= 0;--j) {
- for (auto P : dis) {
- int len, way;
- tie(len, way) = P;
- if (len + j >= y) break;
- add(ne[ len + j ], dp[j] * way);
- }
- }
- DE(all, '\n');
- swap(dp, ne);
- }
- ll le = 0;
- for (int i = 0;i < y;++i)
- add(le, (ll)i * dp[i]);
- for (int i = 2;i < k;++i)
- all = mul(all, i), le = mul(le, i);
- all = mul(all, inv(2)), le = mul(le, inv(2));
- return (all - le + p) % p;
- }
- /*
- ID: ckevin31
- LANG: C++14
- TASK:
- */
- #ifndef KEV
- inline void IO(string name) {
- freopen((name + ".in").c_str(), "r", stdin);
- freopen((name + ".out").c_str(), "w", stdout);
- }
- #else
- inline void IO(string name){}
- #endif
- signed main(){
- ios_base::sync_with_stdio(0), cin.tie(0);
- IO("mooriokart");
- cin >> n >> m >> x >> y;
- init();
- for (int a, b, w;m--;) {
- cin >> a >> b >> w;
- edge[a].pb(b, w);
- edge[b].pb(a, w);
- merge(a, b);
- }
- for (int i = 1;i <= n;++i)
- bfs(i);
- for (int i = 1;i <= n;++i)
- k += i == find(i);
- cout << solve() << '\n';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement