Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // https://informatics.mccme.ru/mod/statements/view3.php?id=24702&chapterid=113441#1
- #include <iostream>
- #include <vector>
- #include <set>
- #define all(a) a.begin(), a.end()
- #define rall(a) a.rbegin(), a.rend()
- // #define file_io
- // #define many_tasks
- #define int int32_t
- #define ll int64_t
- #define uint uint32_t
- #define ull uint64_t
- #define db double
- #define ld long double
- const int MOD = 1e9 + 7;
- int mul(int a, int b) {
- return 1ll * a * b % MOD;
- }
- void ios() {
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(nullptr);
- std::cout.tie(nullptr);
- }
- void dfs(std::vector<std::vector<std::pair<int, int>>> &g, std::vector<int> &tin, std::vector<int> &fup,
- std::vector<bool> &used,
- std::set<int> &ans, int &time, int v, int prev) {
- tin[v] = fup[v] = time++;
- used[v] = true;
- for (auto &elem : g[v]) {
- auto to = elem.first;
- if (to == prev) continue;
- if (used[to]) {
- fup[v] = std::min(fup[v], tin[to]);
- } else {
- dfs(g, tin, fup, used, ans, time, to, v);
- fup[v] = std::min(fup[v], fup[to]);
- if (fup[to] > tin[v]) ans.insert(elem.second);
- }
- }
- }
- void dfs(std::vector<std::vector<std::pair<int, int>>> &g, std::vector<bool> &used, std::set<int> &black,
- std::vector<int> &cs, int cs_num, int v) {
- used[v] = true;
- cs[v] = cs_num;
- for (auto &elem : g[v]) {
- if (!used[elem.first] && black.find(elem.second) == black.end()) {
- dfs(g, used, black, cs, cs_num, elem.first);
- }
- }
- }
- void solve() {
- int n, m;
- std::cin >> n >> m;
- std::vector<std::vector<std::pair<int, int>>> g(n + 1);
- std::vector<int> tin(n + 1), fup(n + 1);
- std::vector<bool> used(n + 1, false);
- std::set<int> ans;
- std::vector<std::pair<int, int>> inp(m);
- for (int i = 0; i < m; ++i) {
- int a, b;
- std::cin >> a >> b;
- g[a].push_back({b, i});
- g[b].push_back({a, i});
- inp[i] = {a, b};
- }
- int time = 0;
- for (int i = 1; i <= n; ++i) {
- if (!used[i]) {
- dfs(g, tin, fup, used, ans, time, i, -1);
- }
- }
- for (int i = 0; i <= n; ++i) used[i] = false;
- std::vector<int> cmp(n + 1, -1);
- int cmp_num = 1;
- for (int i = 1; i <= n; ++i) {
- if (!used[i]) dfs(g, used, ans, cmp, cmp_num++, i);
- }
- std::vector<int> st(cmp_num, 0);
- std::vector<int> cnt(cmp_num, 0);
- for (int i = 1; i <= n; ++i) ++cnt[cmp[i]];
- for (auto &elem : inp) {
- if (cmp[elem.first] != cmp[elem.second]) {
- ++st[cmp[elem.first]];
- ++st[cmp[elem.second]];
- }
- }
- if (cmp_num == 2) {
- std::cout << 1 << ' ' << n;
- return;
- }
- int res = 1;
- int res_cnt = 0;
- for (int i = 1; i < cmp_num; ++i) {
- if (st[i] == 1) {
- res = mul(res, cnt[i]);
- ++res_cnt;
- }
- }
- std::cout << res_cnt << ' ' << res;
- }
- //-----------------------------------------------------------------------------------------------//
- int main() {
- #ifdef file_io
- freopen("C:\\file_io\\input.txt", "r", stdin);
- freopen("C:\\file_io\\output.txt", "w", stdout);
- #endif
- ios();
- #ifdef many_tasks
- size_t t;
- std::cin >> t;
- while (t-- > 0) {
- solve();
- }
- #else
- solve();
- #endif
- return 0;
- }
Add Comment
Please, Sign In to add comment