• UVAlive4287 Proving Equivalences(scc)


    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=10294

    【思路】

           强连通分量。

           求出bcc后,缩点形成DAG,设DAG上入度为0的点数为a 出度为0的点数为b,则ans=max(a,b) (互相到达,首尾相接),需要注意scc数为1的时候ans=0。

    【代码】

     1 #include<cstdio>
     2 #include<stack>
     3 #include<vector>
     4 #include<cstring>
     5 #include<iostream>
     6 using namespace std;
     7 
     8 const int maxn = 20000+10;
     9 
    10 int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
    11 vector<int> G[maxn];
    12 stack<int> S;
    13 
    14 int dfs(int u) {
    15     pre[u]=lowlink[u]=++dfs_clock;
    16     S.push(u);
    17     for(int i=0;i<G[u].size();i++) {
    18         int v=G[u][i];
    19         if(!pre[v]) {
    20             dfs(v);
    21             lowlink[u]=min(lowlink[u],lowlink[v]);
    22         }
    23         else if(!sccno[v]) {
    24             lowlink[u]=min(lowlink[u],pre[v]);
    25         }
    26     }
    27     if(lowlink[u]==pre[u]) {
    28         scc_cnt++;
    29         for(;;) {
    30             int x=S.top(); S.pop();
    31             sccno[x]=scc_cnt;
    32             if(x==u) break;
    33         }
    34     }
    35 }
    36 void find_scc(int n) {
    37     memset(pre,0,sizeof(pre));
    38     memset(sccno,0,sizeof(sccno));
    39     scc_cnt=dfs_clock=0;
    40     for(int i=0;i<n;i++)  
    41     if(!pre[i]) dfs(i);
    42 }
    43 
    44 int T,n,m;
    45 int in0[maxn],out0[maxn];
    46 
    47 int main() {
    48     scanf("%d",&T);
    49     while(T--) {
    50         scanf("%d%d",&n,&m);
    51         for(int i=0;i<n;i++) G[i].clear();
    52         int u,v;
    53         for(int i=0;i<m;i++) {
    54             scanf("%d%d",&u,&v);
    55             u--,v--;
    56             G[u].push_back(v);
    57         }
    58         find_scc(n);
    59         for(int i=1;i<=scc_cnt;i++) in0[i]=out0[i]=1;
    60         for(int i=0;i<n;i++) {
    61             int u=sccno[i];
    62             for(int j=0;j<G[i].size();j++) {
    63                 int v=sccno[G[i][j]];
    64                 if(u!=v) out0[u]=in0[v]=0;
    65             }
    66         }
    67         int a=0,b=0;
    68         for(int i=1;i<=scc_cnt;i++)
    69             a+=in0[i],b+=out0[i];
    70         int ans=scc_cnt==1? 0:max(a,b);
    71         printf("%d
    ",ans);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    读《大道至简》第6章有感
    Java作业05(动手动脑)
    读《大道至简》第五章有感
    java作业04(动手动脑)
    域名与主机名
    STL 迭代器学习
    数组与链表增删改查效率比较
    智能指针多线程安全问题
    快速乘 学习
    关于TCP三个冗余ACK启动快速重传
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5055962.html
Copyright © 2020-2023  润新知