Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <fstream>
- #include <cmath>
- using namespace std;
- const int _SIZE = 200002;
- struct edg
- {
- int to, num;
- edg () {}
- edg(int _to, int _num)
- {
- to = _to;
- num = _num;
- }
- };
- int n, m, timer, timer_in[_SIZE], fup[_SIZE], color[_SIZE];
- bool is_bridge[_SIZE], used[_SIZE], used2[_SIZE];
- vector<vector<edg > > g;
- vector<vector<int > > bridges, new_g;
- void find_bridges(int from, int parent = -1)
- {
- used[from] = 1;
- timer_in[from] = fup[from] = timer++;
- for (int i = 0; i < g[from].size(); ++i)
- {
- int to = g[from][i].to;
- if (to == parent)//для петелек
- continue;
- if (used[to])//если были в следующей вершине
- fup[from] = min(fup[from], timer_in[to]);// то чситаем сколько до верха, до текущей
- else
- {
- find_bridges(to, from);
- fup[from] = min(fup[from], fup[to]);
- if (fup[to] > timer_in[from])
- {
- int freq = 0;
- bool f = 0;
- for (int j = 1; j <= n; ++j)
- {
- if (j == from)
- for (int k = 0; k <= g[j].size(); ++k)
- {
- if(g[j][k].to == to)
- freq++;
- if(freq == 2)
- {
- f = 1;
- break;
- }
- }
- if(f)
- break;
- }
- if(!f)
- {
- is_bridge[g[from][i].num] = 1;
- bridges[from].push_back(to);
- bridges[to].push_back(from);
- }
- }
- }
- }
- }
- void fill_point(int from)
- {
- color[from] = from;
- used2[from] = 1;
- for (int i = 0; i < g[from].size(); ++i)
- {
- int to = g[from][i].to;
- if(!is_bridge[g[from][i].num] && !used2[to])
- {
- color[to] = from;
- used2[to] = 1;
- fill_point(to);
- }
- }
- }
- int main()
- {
- //ifstream cin("input.txt");
- cin >> n >> m;
- g.resize(n + 1);
- bridges.resize(n + 1);
- new_g.resize(n + 1);
- for (int i = 0; i < m; ++i)
- {
- int from, to;
- cin >> from >> to;
- g[from].push_back(edg(to, i));
- g[to].push_back(edg(from, i));
- }
- timer = 0;
- for (int i = 1; i <= n; ++i)
- if (!used[i])
- find_bridges(i);
- for (int i = 1; i <= n; ++i)
- if (!used2[i])
- fill_point(i);
- for (int i = 1; i <= n; ++i)
- for (int j = 0; j < g[i].size(); ++j)
- if (is_bridge[g[i][j].num])
- new_g[color[i]].push_back(color[g[i][j].to]);
- int ans = 0;
- for (int i = 1; i <= n; ++i)
- if (new_g[i].size() == 1)
- ++ans;
- cout << ceil(ans / 2);
- return 0;
- }
- int to, num;
- edg () {}
- edg(int _to, int _num)
- {
- to = _to;
- num = _num;
- }
- };
- int n, m, timer, timer_in[_SIZE], fup[_SIZE], color[_SIZE];
- bool is_bridge[_SIZE], used[_SIZE], used2[_SIZE];
- vector<vector<edg > > g;
- vector<vector<int > > bridges, new_g;
- void find_bridges(int from, int parent = -1)
- {
- used[from] = 1;
- timer_in[from] = fup[from] = timer++;
- for (int i = 0; i < g[from].size(); ++i)
- {
- int to = g[from][i].to;
- if (to == parent)//для петелек
- continue;
- if (used[to])//если были в следующей вершине
- fup[from] = min(fup[from], timer_in[to]);// то чситаем сколько до верха, до текущей
- else
- {
- find_bridges(to, from);
- fup[from] = min(fup[from], fup[to]);
- if (fup[to] > timer_in[from])
- {
- is_bridge[g[from][i].num] = 1;
- bridges[from].push_back(to);
- bridges[to].push_back(from);
- }
- }
- }
- }
- void fill_point(int from)
- {
- color[from] = from;
- used2[from] = 1;
- for (int i = 0; i < g[from].size(); ++i)
- {
- int to = g[from][i].to;
- if(!is_bridge[g[from][i].num])
- {
- if (!used2[to])
- {
- color[to] = from;
- fill_point(to);
- used2[to] = 1;
- }
- }
- }
- }
- int main()
- {
- ifstream cin("input.txt");
- cin >> n >> m;
- g.resize(n + 1);
- bridges.resize(n + 1);
- new_g.resize(n + 1);
- for (int i = 0; i < m; ++i)
- {
- int from, to;
- cin >> from >> to;
- g[from].push_back(edg(to, i));
- g[to].push_back(edg(from, i));
- }
- timer = 0;
- for (int i = 1; i <= n; ++i)
- if (!used[i])
- find_bridges(i);
- for (int i = 1; i <= n; ++i)
- if (!used2[i])
- fill_point(i);
- for (int i = 1; i <= n; ++i)
- for (int j = 0; j < g[i].size(); ++j)
- if (is_bridge[g[i][j].num])
- new_g[color[i]].push_back(color[g[i][j].to]);
- int ans = 0;
- for (int i = 1; i <= n; ++i)
- if (new_g[i].size() == 1)
- ++ans;
- cout << ans;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement