Advertisement
Kevin_Zhang

Untitled

Sep 21st, 2020
340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.85 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #define pb emplace_back
  3. using namespace std;
  4. using ll = long long;
  5. #ifdef KEV
  6. #define DE(i, e) cerr << #i << ' ' << i << e
  7. void debug(auto L, auto R) { while (L < R) cerr << *L << " \n"[L+1==R], ++L; }
  8. #else
  9. #define DE(...) 0
  10. void debug(...) {}
  11. #endif
  12. const int maxn = 2510, p = 1e9+7;
  13. #define int ll
  14. int dp[maxn], n, cnt[maxn][maxn], x, y, m, k, tmp[maxn];
  15. vector<pair<int,int>> edge[maxn];
  16. int g[maxn], sz[maxn];
  17. void init() {
  18.     for (int i = 1;i <= n;++i)
  19.         g[i] = i, sz[i] = 1;
  20. }
  21. int find(int i) { return g[i] == i ? i : g[i] = find(g[i]); }
  22. void merge(int a, int b) {
  23.     a = find(a), b = find(b);
  24.     if (a == b) return;
  25.     if (sz[a] < sz[b]) swap(a, b);
  26.     sz[a] += sz[b];
  27.     g[b] = a;
  28. }
  29. void bfs(int s) {
  30.     static int dis[maxn];
  31.     fill(dis, dis+n+1, -1);
  32.     dis[s] = 0;
  33.     queue<int> togo;
  34.     togo.push(s);
  35.     int G = find(s);
  36.     while (togo.size()) {
  37.         int now = togo.front();
  38.         togo.pop();
  39.         if (now != s)
  40.             ++cnt[ G ][ min(y, dis[now]) ];
  41.         for (auto E : edge[now]) {
  42.             int u, w;
  43.             tie(u, w) = E;
  44.             if (dis[u] == -1) {
  45.                 dis[u] = dis[now] + w;
  46.                 togo.push(u);
  47.             }
  48.         }
  49.     }
  50. }
  51. int mul(ll a, ll b) { return a * b % p; }
  52. //void add(int &v, ll val) { v = (v + val) % p; }
  53. void add(ll &v, ll val) { v = (v + val) % p; }
  54. ll inv(int v) { return v == 1 ? 1 : (p - p / v) * inv(p % v) % p; }
  55. ll solve() {
  56.     dp[0] = 1;
  57.     ll all = 0, way = 1;
  58.     int *dp = ::dp, *ne = ::tmp;
  59.  
  60.     for (int i = 1;i <= n;++i) if (i == find(i)) {
  61.         ll tmp = 0, cy = 0;
  62.         for (int j = 0;j <= y;++j) if(cnt[i][j]) {
  63.             add(tmp, (ll)(j+x) * cnt[i][j] % p * way);
  64.             cy += cnt[i][j];
  65.         }
  66.         way = mul(way, cy);
  67.         all = mul(all, cy);
  68.         add(all, tmp);
  69.         fill(ne, ne+y, 0);
  70.  
  71.         vector<pair<int,int>> dis;
  72.         for (int j = 0;j < y;++j)
  73.             if (cnt[i][j]) dis.pb(j + x, cnt[i][j]);
  74.  
  75. //      for (auto [len, way] : dis)
  76. //          DE(len, ' '), DE(way, '\n');
  77.  
  78.         for (int j = y-1;j >= 0;--j) {
  79.             for (auto P : dis) {
  80.                 int len, way;
  81.                 tie(len, way) = P;
  82.                 if (len + j >= y) break;
  83.                 add(ne[ len + j ], dp[j] * way);
  84.             }
  85.         }
  86.         DE(all, '\n');
  87.         swap(dp, ne);
  88.     }
  89.     ll le = 0;
  90.     for (int i = 0;i < y;++i)
  91.         add(le, (ll)i * dp[i]);
  92.  
  93.     for (int i = 2;i < k;++i)
  94.         all = mul(all, i), le = mul(le, i);
  95.  
  96.     all = mul(all, inv(2)), le = mul(le, inv(2));
  97.     return (all - le + p) % p;
  98. }
  99. /*
  100. ID: ckevin31
  101. LANG: C++14
  102. TASK:
  103. */
  104. #ifndef KEV
  105. inline void IO(string name) {
  106.     freopen((name + ".in").c_str(), "r", stdin);
  107.     freopen((name + ".out").c_str(), "w", stdout);
  108. }
  109. #else
  110. inline void IO(string name){}
  111. #endif
  112. signed main(){
  113.     ios_base::sync_with_stdio(0), cin.tie(0);
  114.     IO("mooriokart");
  115.     cin >> n >> m >> x >> y;
  116.     init();
  117.     for (int a, b, w;m--;) {
  118.         cin >> a >> b >> w;
  119.         edge[a].pb(b, w);
  120.         edge[b].pb(a, w);
  121.         merge(a, b);
  122.     }
  123.     for (int i = 1;i <= n;++i)
  124.         bfs(i);
  125.     for (int i = 1;i <= n;++i)
  126.         k += i == find(i);
  127.     cout << solve() << '\n';
  128. }
  129.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement