强连通分量Tarjan模板

来源:互联网 发布:热血传奇装备数据库 编辑:程序博客网 时间:2024/05/12 21:14

模板对应POJ1236

#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 110;int n, m, head[N], cnt, sum, visit[N];struct go{int e, next;}edge[N * N];void addedge(int a, int b){edge[cnt].e = b;edge[cnt].next = head[a];head[a] = cnt++;}/********************Tarjan********************/int dfn[N], low[N], idx, a, scc[N];  int vis[N], stack[N], tot;     int tarjanDFS(int to){      vis[to] = 1;      stack[++idx] = to;      low[to] = dfn[to] = ++a;      for(int it = head[to];it != -1;it = edge[it].next){    int end = edge[it].e;        if(!vis[end]){              tarjanDFS(end);              low[to] = min(low[to], low[end]);          }          if(vis[end] == 1)              low[to] = min(dfn[end], low[to]);      }      if(dfn[to] == low[to]){          tot++;          int e;          do{              e = stack[idx--];              scc[e] = tot;              vis[e] = 2;          }while(e != to);       }  }    int tarjan(int n){      idx = 0, tot = 0, a = 0;      memset(vis, 0, sizeof(vis));      memset(dfn, 0, sizeof(dfn));      for(int i = 1;i <= n;i++)          if(!vis[i])              tarjanDFS(i);      return tot;  }  /*********************END**********************/  void solve(){int i, it, inde[N], outde[N];memset(inde, 0, sizeof(inde));memset(outde, 0, sizeof(outde));memset(visit, 0, sizeof(visit));tarjan(n);vector<int> v[N];for(i = 1;i <= n;i++)for(it = head[i];it != -1;it = edge[it].next){int end = edge[it].e;if(scc[i] != scc[end]){v[scc[i]].push_back(scc[end]);inde[scc[end]]++;outde[scc[i]]++;}}int res = 0, son = 0;for(i = 1;i <= tot;i++){if(outde[i] == 0)son++;if(inde[i] == 0)res++;}cout << res << endl;if(tot == 1){cout << 0 << endl;return ;}cout << max(son, res) << endl;return ;}int main(){while(~scanf("%d", &n)){int i, a;cnt = 0;memset(head, -1, sizeof(head));for(i = 1;i <= n;i++){while(scanf("%d", &a)&&a)addedge(i, a);}solve();}return 0;}