Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
457
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.90 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int MOD = 1000000007;
  6. const int N = 100010;
  7. const int B = 100;
  8.  
  9. inline int add(int u, int v) {
  10. return (u += v) >= MOD ? u - MOD : u;
  11. }
  12.  
  13. inline int sub(int u, int v) {
  14. return (u -= v) < 0 ? u + MOD : u;
  15. }
  16.  
  17. inline int mul(int u, int v) {
  18. return (long long)u * v % MOD;
  19. }
  20.  
  21. inline int power(int u, int v) {
  22. int res = 1;
  23. while (v) {
  24. if (v & 1) res = mul(res, u);
  25. u = mul(u, u);
  26. v >>= 1;
  27. }
  28. return res;
  29. }
  30.  
  31. int n, m, c;
  32. vector<int> adj[N];
  33. int deg[N];
  34. int f[2][N];
  35.  
  36. int dp[2][B][B];
  37. int lv[B];
  38. vector<int> bigAdj[B];
  39. int isGood[B];
  40. bool used[B];
  41. vector<int> colors;
  42. map<pair<vector<int>, pair<int, int>>, int> cache;
  43.  
  44. pair<int, int> go(int u, int v) {
  45. int cnt = 0;
  46. while (deg[v] == 2) {
  47. cnt++;
  48. vector<int> ls;
  49. for (int w : adj[v]) {
  50. if (deg[w] < 2) continue;
  51. ls.push_back(w);
  52. }
  53. assert(ls.size() == 2);
  54. if (ls[0] == u) swap(ls[0], ls[1]);
  55. u = v;
  56. v = ls[0];
  57. }
  58. return {v, cnt};
  59. }
  60.  
  61. void dfsInit(int u) {
  62. used[u] = 1;
  63. for (int v : bigAdj[u]) {
  64. if (used[v]) {
  65. if (lv[v] + 1 < lv[u]) isGood[v] = 1;
  66. } else {
  67. lv[v] = lv[u] + 1;
  68. dfsInit(v);
  69. }
  70. }
  71. }
  72.  
  73. int dfs(int u, int colorOfPar) {
  74. if (cache.count({colors, {u, colorOfPar}})) return cache[{colors, {u, colorOfPar}}];
  75. int res = 0;
  76. int maxColor = *max_element(colors.begin(), colors.end());
  77. for (int i = 1; i <= maxColor; i++) {
  78. int now = 1;
  79. for (int v : bigAdj[u]) {
  80. assert(lv[v] != lv[u]);
  81. if (lv[v] > lv[u]) continue;
  82. if (lv[v] + 1 == lv[u]) {
  83. now = mul(now, dp[colorOfPar != i][u][v]);
  84. }
  85. if (lv[v] + 1 < lv[u]) {
  86. now = mul(now, dp[colors[v] != i][u][v]);
  87. }
  88. }
  89.  
  90. if (now == 0) continue;
  91.  
  92. if (isGood[u]) colors[u] = i;
  93. else colors[u] = 0;
  94. for (int v : bigAdj[u]) {
  95. if (lv[v] != lv[u] + 1) continue;
  96. now = mul(now, dfs(v, i));
  97. }
  98. colors[u] = 0;
  99.  
  100. res = add(res, now);
  101. }
  102. if (colorOfPar > maxColor) {
  103. int equalsToPar = 1;
  104. int diffToPar = c - maxColor - 1;
  105. for (int v : bigAdj[u]) {
  106. assert(lv[v] != lv[u]);
  107. if (lv[v] > lv[u]) continue;
  108. if (lv[v] + 1 == lv[u]) {
  109. equalsToPar = mul(equalsToPar, dp[0][u][v]);
  110. diffToPar = mul(diffToPar, dp[1][u][v]);
  111. }
  112. if (lv[v] + 1 < lv[u]) {
  113. equalsToPar = mul(equalsToPar, dp[1][u][v]);
  114. diffToPar = mul(diffToPar, dp[1][u][v]);
  115. }
  116. }
  117. int now = add(equalsToPar, diffToPar);
  118. if (now > 0) {
  119. if (isGood[u]) colors[u] = maxColor + 1;
  120. else colors[u] = 0;
  121. for (int v : bigAdj[u]) {
  122. if (lv[v] != lv[u] + 1) continue;
  123. now = mul(now, dfs(v, maxColor + 1));
  124. }
  125. colors[u] = 0;
  126.  
  127. res = add(res, now);
  128. }
  129. } else {
  130. int now = c - maxColor;
  131. for (int v : bigAdj[u]) {
  132. assert(lv[v] != lv[u]);
  133. if (lv[v] > lv[u]) continue;
  134. if (lv[v] + 1 == lv[u]) {
  135. now = mul(now, dp[1][u][v]);
  136. }
  137. if (lv[v] + 1 < lv[u]) {
  138. now = mul(now, dp[1][u][v]);
  139. }
  140. }
  141. if (now > 0) {
  142. if (isGood[u]) colors[u] = maxColor + 1;
  143. else colors[u] = 0;
  144. for (int v : bigAdj[u]) {
  145. if (lv[v] != lv[u] + 1) continue;
  146. now = mul(now, dfs(v, maxColor + 1));
  147. }
  148. colors[u] = 0;
  149.  
  150. res = add(res, now);
  151. }
  152. }
  153. cache[{colors, {u, colorOfPar}}] = res;
  154. return res;
  155. }
  156.  
  157. int main() {
  158. ios_base::sync_with_stdio(0);
  159. cin.tie(0);
  160. cin >> n >> m >> c;
  161. for (int i = 1; i <= m; i++) {
  162. int u, v;
  163. cin >> u >> v;
  164. adj[u].push_back(v);
  165. adj[v].push_back(u);
  166. deg[u]++, deg[v]++;
  167. }
  168. if (c == 1) {
  169. if (m == 0) cout << 1 << endl;
  170. else cout << 0 << endl;
  171. return 0;
  172. }
  173. if (m == n - 1) {
  174. cout << mul(c, power(c - 1, n - 1)) << endl;
  175. return 0;
  176. }
  177. queue<int> q;
  178. for (int i = 1; i <= n; i++) {
  179. if (deg[i] == 1) q.push(i);
  180. }
  181. int res = 1;
  182. while (!q.empty()) {
  183. int u = q.front();
  184. q.pop();
  185. res = mul(res, c - 1);
  186. for (int v : adj[u]) {
  187. deg[v]--;
  188. if (deg[v] == 1) {
  189. q.push(v);
  190. }
  191. }
  192. }
  193.  
  194. f[0][0] = 0;
  195. f[0][1] = c - 1;
  196. f[1][0] = 1;
  197. f[1][1] = c - 2;
  198.  
  199. for (int i = 2; i < N; i++) {
  200. f[0][i] = add(mul(f[0][i - 2], f[0][1]), mul(mul(f[1][i - 2], f[1][1]), c - 1));
  201. f[1][i] = add(mul(f[0][i - 2], f[1][1]), mul(f[1][i - 2], f[0][1]));
  202. f[1][i] = add(f[1][i], mul(mul(f[1][i - 2], f[1][1]), c - 2));
  203. }
  204.  
  205. int num = 0;
  206. vector<int> bigVertices;
  207. for (int i = 1; i <= n; i++) {
  208. if (deg[i] >= 3) bigVertices.push_back(i);
  209. num += deg[i] >= 2;
  210. }
  211. if (bigVertices.empty()) {
  212. res = mul(res, c);
  213. res = mul(res, f[0][num - 1]);
  214. cout << res << endl;
  215. return 0;
  216. }
  217. sort(bigVertices.begin(), bigVertices.end());
  218. for (int i = 0; i < bigVertices.size(); i++) {
  219. for (int j = 0; j < bigVertices.size(); j++) {
  220. dp[0][i][j] = dp[1][i][j] = 1;
  221. }
  222. }
  223. for (int i = 0; i < bigVertices.size(); i++) {
  224. int u = bigVertices[i];
  225. vector<int> toSelf;
  226. for (int v : adj[u]) {
  227. if (deg[v] >= 2) {
  228. pair<int, int> foo = go(u, v);
  229. if (foo.first == u) {
  230. toSelf.push_back(foo.second);
  231. continue;
  232. }
  233. int id = lower_bound(bigVertices.begin(), bigVertices.end(), foo.first) - bigVertices.begin();
  234. dp[0][i][id] = mul(dp[0][i][id], f[0][foo.second]);
  235. dp[1][i][id] = mul(dp[1][i][id], f[1][foo.second]);
  236. bigAdj[i].push_back(id);
  237. }
  238. }
  239. sort(toSelf.begin(), toSelf.end());
  240. for (int j = 0; j < toSelf.size(); j += 2) {
  241. res = mul(res, f[0][toSelf[j]]);
  242. }
  243. }
  244. for (int i = 0; i < bigVertices.size(); i++) {
  245. sort(bigAdj[i].begin(), bigAdj[i].end());
  246. bigAdj[i].resize(unique(bigAdj[i].begin(), bigAdj[i].end()) - bigAdj[i].begin());
  247. }
  248.  
  249. colors.resize(bigVertices.size(), 0);
  250. dfsInit(0);
  251. int now = dfs(0, 0);
  252. res = mul(res, now);
  253. cout << res << endl;
  254. return 0;
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement