danielvitor23

Graph Coloring - LightOJ

Apr 26th, 2021 (edited)
1,376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.80 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int INF = 0x3f3f3f3f;
  4. const int64_t MOD = 1e9+7;
  5.  
  6. int64_t extended_gcd(int64_t a, int64_t b, int64_t &x, int64_t &y) {
  7.     if (b == 0) {
  8.         x = 1; y = 0;
  9.         return a;
  10.     }
  11.     int64_t g = extended_gcd(b, a%b, y, x);
  12.     y -= x*(a/b);
  13.     return g;
  14. }
  15. inline int64_t modSum(int64_t a, int64_t b, int64_t mod = MOD) {
  16.     return (a+b >= mod ? a+b-mod : a+b);
  17. }
  18. inline int64_t modSub(int64_t a, int64_t b, int64_t mod = MOD) {
  19.     return (a-b < 0 ? a-b+mod : a-b);
  20. }
  21. inline int64_t modMul(int64_t a, int64_t b, int64_t mod = MOD) {
  22.     return (a*b)%mod;
  23. }
  24. int64_t inv_mod(int64_t a, int64_t m = MOD) {
  25.     int64_t x, y;
  26.   extended_gcd(a, m, x, y);
  27.     return (x%m + m)%m;
  28. }
  29. int64_t modDiv(int64_t a, int64_t b, int64_t mod = MOD) {
  30.     return modMul(a, inv_mod(b, mod), mod);
  31. }
  32. int64_t binpow(int64_t base, int exp, int mod = MOD) {
  33.     int64_t ans = 1;
  34.     while (exp > 0) {
  35.         if (exp & 1) ans = modMul(ans, base, mod);
  36.         base = modMul(base, base, mod);
  37.         exp >>= 1;
  38.     }
  39.     return ans;
  40. }
  41.  
  42. template<typename T>
  43. struct Matrix {
  44.     std::vector<std::vector<T>> mat;
  45.     Matrix(int n, int m, bool id = false) {
  46.         mat.resize(n, std::vector<T>(m, 0));
  47.         if (id) for (int i = 0; i < n; ++i)
  48.             mat[i][i] = 1;
  49.     }
  50. };
  51.  
  52. // Gaussian elimination with partial pivot (avoids propagation of rounding errors)
  53. pair<int, int> gaussianElimination(Matrix<int64_t> a, Matrix<int64_t> &ans, int64_t k) {
  54.     int n = (int)a.mat.size();
  55.     int m = (int)a.mat[0].size()-1;
  56.     std::vector<int> end(m, -1);
  57.  
  58.     for (int col = 0, row = 0; col < m and row < n; ++col) {
  59.         int l = row;
  60.  
  61.         // Which row has largest column value
  62.         for (int i = row; i < n; ++i)
  63.             if (abs(a.mat[i][col]) > abs(a.mat[l][col]))
  64.                 l = i;
  65.         if (a.mat[l][col] == 0)
  66.             continue;
  67.         for (int i = col; i <= m; ++i)
  68.             swap(a.mat[row][i], a.mat[l][i]);
  69.         end[col] = row;
  70.  
  71.         // Elimination phase
  72.         for (int i = 0; i < n; ++i) if (i != row) {
  73.             int64_t c = modDiv(a.mat[i][col], a.mat[row][col], k);
  74.             for (int j = m; j >= col; --j) {
  75.                 a.mat[i][j] = modSub(a.mat[i][j], modMul(a.mat[row][j], c, k), k);
  76.             }
  77.         }
  78.         ++row;
  79.     }
  80.  
  81.     // Substitution phase
  82.     for (int i = 0; i < m; ++i)
  83.         if (end[i] != -1)
  84.             ans.mat[i][0] = modDiv(a.mat[end[i]][m], a.mat[end[i]][i], k);
  85.  
  86.     for (int i = 0; i < n; ++i) {
  87.         int64_t sum = 0;
  88.         for (int j = 0; j < m; ++j)
  89.             sum = modSum(sum, modMul(ans.mat[j][0], a.mat[i][j], k), k);
  90.         if (sum != a.mat[i][m])
  91.             return {0, 0}; // No solution
  92.     }
  93.  
  94.     int cnt = 0;
  95.     for (int i = 0; i < m; ++i)
  96.         if (end[i] == -1)
  97.             ++cnt;
  98.  
  99.     if (cnt) return {INF, cnt}; // Infinite solutions
  100.  
  101.     return {1, 0}; // One solution
  102. }
  103.  
  104. int tc;
  105. int n, m;
  106. int64_t k;
  107.  
  108. int main() {
  109.     cin.tie(0)->sync_with_stdio(0);
  110.     cin >> tc;
  111.     for (int t = 1; t <= tc; ++t) {
  112.         cout << "Case " << t << ": ";
  113.         cin >> n >> m >> k;
  114.         vector<vector<int>> gr(n, vector<int>());
  115.         for (int i = 0, a, b; i < m; ++i) {
  116.             cin >> a >> b, --a, --b;
  117.             gr[a].push_back(b);
  118.             gr[b].push_back(a);
  119.         }
  120.         Matrix<int64_t> a(n, n+1);
  121.         for (int i = 0; i < n; ++i) {
  122.             a.mat[i][i] = 1;
  123.             for (int to : gr[i]) {
  124.                 a.mat[i][to] = k-1;
  125.             }
  126.         }
  127.         Matrix<int64_t> ans(n, 1);
  128.         auto [ret, qtd] = gaussianElimination(a, ans, k);
  129.         if (ret <= 1) {
  130.             cout << ret << '\n';
  131.         } else {
  132.             cout << binpow(k, qtd, MOD) << '\n';
  133.         }
  134.     }
  135. }
Advertisement
Add Comment
Please, Sign In to add comment