數算實習 popular cow 強連通分量tarjan演算法
阿新 • • 發佈:2018-12-20
popular cow 描述:有N頭牛。如果a喜歡b,b喜歡c,則a也會喜歡c。告訴你M個喜歡關係 ,比如(a,b)表示a喜歡b。問有多少頭牛是被所有牛都喜歡的。 N<= 10,000, M<= 50,000
樣例輸入 3 3 1 2 2 1 2 3
樣例輸出1
#include <iostream> #include <algorithm> #include <string> #include <cstring> #include <stack> #include <vector> using namespace std; int n, m; int visited[10005] = { 0 }; //記錄是否被訪問 int dfn[10005] = { 0 }; //遍歷 int low[10005] = { 0 }; //可到達的最小結點 int ntime = 0; stack<int> s; vector<int> v[10005]; //記錄邊 int color[10005] = { 0 }; //用於染色 int curcolor = 1; void tarjan(int u) { visited[u] = 1; s.push(u); dfn[u] = ++ntime; low[u] = ntime; for (int i = 0; i < v[u].size(); i++) { int q = v[u][i]; if (visited[q] == 0) { tarjan(q); low[u] = min(low[u], low[q]); } else low[u] = min(low[u], dfn[q]); } if (dfn[u] == low[u]) { int v = s.top(); s.pop(); while (v != u) //染色 { color[v] = curcolor; v = s.top(); s.pop(); } color[u] = curcolor; curcolor++; } } int sum[10005] = { 0 }; int main() { cin >> n >> m; for (int i = 0; i < m; i++) { int a, b; cin >> a >> b; v[a].push_back(b); } for (int i = 1; i <= n; i++) { if (visited[i] == 0) tarjan(i); } for (int i = 1; i <= n; i++) { for (int j = 0; j < v[i].size(); j++) { int k = v[i][j]; if (color[i] != color[k]) sum[color[i]]++; } } int r = 0; int flag; for (int i = 1; i < curcolor; i++) { if (sum[i] == 0) { r++; flag = i; } } if (r >= 2) cout << "0" << endl; else { int result = 0; for (int i = 1; i <= n; i++) { if (color[i] == flag) result++; } cout << result << endl; } return 0; }