zoukankan      html  css  js  c++  java
  • Tarjan UVALive 6511 Term Project

    题目传送门

     1 /*
     2     题意:第i个人选择第a[i]个人,问组成强联通分量(自己连自己也算)外还有多少零散的人
     3     有向图强联通分量-Tarjan算法:在模板上加一个num数组,记录每个连通分量的点数,若超过1,则将连通点数相加
     4         用总点数-ans则是零散的点
     5     详细解释:http://www.bubuko.com/infodetail-927304.html
     6 */
     7 #include <cstdio>
     8 #include <cstring>
     9 #include <algorithm>
    10 #include <vector>
    11 #include <stack>
    12 using namespace std;
    13 
    14 const int MAXN = 1e5 + 10;
    15 const int INF = 0x3f3f3f3f;
    16 vector<int> G[MAXN];
    17 stack<int> S;
    18 int pre[MAXN], low[MAXN];
    19 int instack[MAXN], num[MAXN];
    20 int dfs_clock, scc_cnt;
    21 int n, ans;
    22 
    23 void DFS(int u)
    24 {
    25     instack[u] = 1;
    26     pre[u] = low[u] = ++dfs_clock;
    27     S.push (u);
    28     for (int i=0; i<G[u].size (); ++i)
    29     {
    30         int v = G[u][i];
    31         if (!pre[v])
    32         {
    33             DFS (v);    low[u] = min (low[u], low[v]);
    34         }
    35         else if (instack[v] == 1)
    36         {
    37             low[u] = min (low[u], pre[v]);
    38         }
    39     }
    40 
    41     if (low[u] == pre[u])
    42     {
    43         scc_cnt++;
    44         for (; ; )
    45         {
    46             int x = S.top ();    S.pop ();
    47             instack[x] = 0;
    48             num[scc_cnt]++;
    49             if (x == u)    break;
    50         }
    51     }
    52 }
    53 
    54 void Tarjan(void)
    55 {
    56     dfs_clock = scc_cnt = 0;
    57     memset (pre, 0, sizeof (pre));
    58     memset (low, 0, sizeof (low));
    59     memset (num, 0, sizeof (num));
    60     memset (instack, 0, sizeof (instack));
    61     while (!S.empty ())    S.pop ();
    62 
    63     for (int i=1; i<=n; ++i)
    64     {
    65         if (!pre[i])    DFS (i);
    66     }
    67 }
    68 
    69 int main(void)        //UVALive 6511 Term Project
    70 {
    71     freopen ("L.in", "r", stdin);
    72 
    73     int t;    scanf ("%d", &t);
    74     while (t--)
    75     {
    76         ans = 0;    scanf ("%d", &n);
    77         for (int i=1; i<=n; ++i)    G[i].clear ();
    78         for (int i=1; i<=n; ++i)
    79         {
    80             int x;    scanf ("%d", &x);
    81             G[i].push_back (x);
    82             if (i == x)    ans++;
    83         }
    84 
    85         Tarjan ();
    86         for (int i=1; i<=scc_cnt; ++i)
    87         {
    88             if (num[i] > 1)    ans += num[i];
    89         }
    90         printf ("%d
    ", n - ans);
    91     }
    92 
    93     return 0;
    94 }
    编译人生,运行世界!
  • 相关阅读:
    【试水CAS-4.0.3】第07节_CASclient配置单点登录
    30分钟,让你彻底明白Promise原理
    【你离硅谷只差一步】网易中国创业家大赛项目火热征集中
    21分钟学会写编译器
    Android 模拟器下载、编译及调试
    GitLab 自动触发 Jenkins 构建
    微服务监控探索
    感觉要火!妹子实地采访网易猪厂程序员七夕怎么过
    延迟任务调度系统—技术选型与设计(下篇)
    使用QUIC
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4595790.html
Copyright © 2011-2022 走看看