链接:
题意:
给你一个有向图,求其中的所有强联通分量中点最少的(1不算)
题解:
直接求强联通分量,并在pop的时候算出个数,更新ans
代码:
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6 #include <cstdio> 7 #include <string> 8 #include <vector> 9 #include <cstdlib> 10 #include <cstring> 11 #include <sstream> 12 #include <iostream> 13 #include <algorithm> 14 #include <functional> 15 using namespace std; 16 #define rep(i,a,n) for (int i=a;i<n;i++) 17 #define per(i,a,n) for (int i=n-1;i>=a;i--) 18 #define all(x) (x).begin(),(x).end() 19 #define pb push_back 20 #define mp make_pair 21 #define lson l,m,rt<<1 22 #define rson m+1,r,rt<<1|1 23 typedef long long ll; 24 typedef vector<int> VI; 25 typedef pair<int, int> PII; 26 const ll MOD = 1e9 + 7; 27 const int INF = 0x3f3f3f3f; 28 const int MAXN = 2e5 + 7; 29 // head 30 31 int n, order = 0; 32 int low[MAXN], dfn[MAXN]; 33 int vis[MAXN]; 34 VI G[MAXN]; 35 stack<int> S; 36 int ans = INF; 37 38 void tarjan(int u) { 39 dfn[u] = low[u] = ++order; 40 S.push(u); vis[u] = 1; 41 rep(i, 0, G[u].size()) { 42 int v = G[u][i]; 43 if (!dfn[v]) { 44 tarjan(v); 45 low[u] = min(low[u], low[v]); 46 } 47 else low[u] = min(low[u], dfn[v]); 48 } 49 if (low[u] == dfn[u]) { 50 int cnt = 0; 51 while (1) { 52 int now = S.top(); S.pop(); 53 vis[u] = 0; 54 cnt++; 55 if (now == u) break; 56 } 57 if (cnt > 1) ans = min(ans, cnt); 58 } 59 } 60 61 int main() { 62 cin >> n; 63 rep(i, 0, n) { 64 int x; 65 scanf("%d", &x); 66 x--; 67 G[i].pb(x); 68 } 69 rep(i, 0, n) if (!dfn[i]) tarjan(i); 70 cout << ans << endl; 71 return 0; 72 }