Advertisement
Guest User

Untitled

a guest
Apr 29th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.44 KB | None | 0 0
  1. #include <vector>
  2. #include <cstdio>
  3. #include <iostream>
  4. #include <set>
  5.  
  6.  
  7. using namespace std;
  8.  
  9. void dfs_harvest(int vertex, vector<bool>&visited, vector<vector<int> >&adj, vector<int>&segment){
  10.     if (visited[vertex]) return;
  11.     visited[vertex] = true;
  12.     segment.push_back(vertex);
  13.     for (int i = 0; i < adj[vertex].size(); i++){
  14.         dfs_harvest(adj[vertex][i], visited, adj, segment);
  15.     }
  16. }
  17.  
  18. vector<vector<int> > find_segments(int n, vector<vector<int> >&adj){
  19.     vector<bool>visited(n,false);
  20.     vector<vector<int> > result;
  21.     for (int vertex = 0; vertex < n; vertex++){
  22.         if (visited[vertex]) continue;
  23.         vector<int>segment;
  24.         dfs_harvest(vertex, visited, adj, segment);
  25.         result.push_back(segment);
  26.     }
  27.     return result;
  28. }
  29.  
  30. void find_bridges(int u, vector<bool>&visited, vector<int>& disc, vector<int>&low, vector<int>&parent, vector<vector<int> >&adj, vector<pair<int, int> >&bridges){
  31.     static int time = 0;
  32.     visited[u] = true;
  33.     disc[u] = low[u] = ++time;
  34.     for (int i = 0; i < adj[u].size(); i++)
  35.     {
  36.         int v = adj[u][i];
  37.         if (!visited[v])
  38.         {
  39.             parent[v] = u;
  40.             find_bridges(v, visited, disc, low, parent, adj, bridges);
  41.  
  42.             low[u]  = min(low[u], low[v]);
  43.  
  44.             if (low[v] > disc[u]){
  45.                 bridges.push_back(make_pair(u,v));
  46.             }
  47.         }
  48.         else if (v != parent[u])
  49.             low[u]  = min(low[u], disc[v]);
  50.     }
  51. }
  52.  
  53. int main(int argc, char const *argv[])
  54. {
  55.     int n, m;
  56.     scanf("%d %d", &n, &m);
  57.     vector<vector<int> >adj;
  58.     for (int i = 0; i < n; i++){
  59.         vector<int>t;
  60.         adj.push_back(t);
  61.     }
  62.     set<pair<int, int> >adj_set;
  63.     for (int i = 0; i < m; i++){
  64.         int v1,v2;
  65.         scanf("%d %d", &v1, &v2);
  66.         v1--; v2--;
  67.         adj[v1].push_back(v2);
  68.         adj[v2].push_back(v1);
  69.         adj_set.insert(make_pair(v1,v2));
  70.         adj_set.insert(make_pair(v2,v1));
  71.     }
  72.     vector<pair<int, int> >bridges;
  73.     vector<bool>visited(n, false);
  74.     vector<bool>visited2(n, false);
  75.     vector<int>disc(n,0);
  76.     vector<int>parent(n, -1);
  77.     vector<int>low(n,0);
  78.     for (int i = 0; i < n; i++){
  79.         find_bridges(i, visited, disc, low, parent, adj, bridges);
  80.     }
  81.  
  82.     vector<int>bridge_endpoint(n,0);
  83.     for (int i = 0; i < bridges.size(); i++){
  84.         int v1 = bridges[i].first;
  85.         int v2 = bridges[i].second;
  86.         bridge_endpoint[v1] += 1;
  87.         bridge_endpoint[v2] += 1;
  88.         adj_set.erase(adj_set.find(make_pair(v1,v2)));
  89.         adj_set.erase(adj_set.find(make_pair(v2,v1)));
  90.     }
  91.     vector<vector<int> >adj_b;
  92.     for (int i = 0; i < n; i++){
  93.         vector<int>t;
  94.         adj_b.push_back(t);
  95.     }
  96.     set<pair<int, int> >::iterator it;
  97.     for (it = adj_set.begin(); it != adj_set.end(); ++it){
  98.         int v1 = (*it).first;
  99.         int v2 = (*it).second;
  100.         adj_b[v1].push_back(v2);
  101.     }
  102.     long long options = 1;
  103.     int shops_needed = 0;
  104.     vector<vector<int> >blocks = find_segments(n, adj_b);
  105.     for (int i = 0; i < blocks.size(); i++){
  106.         bool ok = true;
  107.         for (int j = 0; j < blocks[i].size(); j++){
  108.             if (bridge_endpoint[blocks[i][j]] > 1) ok = false;
  109.         }
  110.         if (ok){
  111.             shops_needed ++;
  112.             options = (options * blocks[i].size()) % 1000000007ll;
  113.         }
  114.     }
  115.     printf("%d %lld\n", shops_needed, options);
  116.     return 0;
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement