LuoGu-P2863牛的舞会The Cow Prom[tarjan 缩点模板]
传送门:https://www.luogu.org/problemnew/show/P2863
思路:tarjan模板题,之前会的tarjan,一直想学缩点到底是什么操作,发现就是把同组的放在一个数组里(并查集可能又会有),或者重新建图;不知道为什么百度不到讲缩点的blog。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <map> #include <set> #include <queue> #include <list> #include <iterator> #define lson (l , mid , rt << 1) #define rson (mid + 1 , r , rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << "\n"; #define pb push_back typedef long long ll; using namespace std; const int maxn = 10009; int n,m; vector<int >mp[maxn]; int dfn[maxn],low[maxn],ind; int stk[maxn],p; bool vis[maxn]; int ans = 0, cnt = 0; int q[maxn]; void tarjan(int x) { ind++; dfn[x] = low[x] = ind; vis[x] = true; stk[++p] = x; for(int i=0;i<mp[x].size();i++) { int to = mp[x][i]; if(dfn[to]==0) { tarjan(to); low[x] = min(low[x],low[to]); } else if(vis[to]) { low[x] = min(low[x],dfn[to]); } } if(low[x]==dfn[x]) { cnt++; while(1) { int tmp = stk[p--]; q[cnt]++; vis[tmp]=false; if(tmp==x)break; } } } int main(){ scanf("%d%d", &n,&m); for(int i=1; i<=m; i++) { int u,v; scanf("%d%d", &u,&v); mp[u].pb(v); } for(int i=1; i<=n; i++) { if(dfn[i]==0) { tarjan(i); } } for(int i=1;i<=cnt;i++) if(q[i]>1)ans++; printf("%d\n",ans); return 0; }
skr