• NYOJ 120校园网络(有向图的强连通分量)(Kosaraju算法)


    找出各个顶点所属的连通分量,将连通分量的点看作一个点,求这些顶点入度为0的个数和出度0的个数,取最大的即可。

     1 #include<iostream>
     2 #include<vector>
     3 #include<cstdio>
     4 #include<cstring>
     5 #define maxn 102
     6 using namespace std;
     7 vector<int> G[maxn],G2[maxn];
     8 vector<int> s;//
     9 int vis[maxn],
    10     sccno[maxn],                            //标记顶点所属的连通分量
    11     scc_cnt;                                 //记录有几个强连通分量
    12 void dfs1(int u)
    13 {
    14     if(vis[u]) return ;                     //顶点遍历过则返回
    15     vis[u] = 1;
    16     for(int i=0; i<G[u].size(); i++)dfs1(G[u][i]);
    17     s.push_back(u);                         //将一颗树上的顶点入栈
    18 }
    19 void dfs2(int u)
    20 {
    21     if(sccno[u])return ;
    22     sccno[u] = scc_cnt;                     //标记顶点所属的连通分量
    23     for(int i=0; i<G2[u].size(); i++)dfs2(G2[u][i]);
    24 }
    25 void find_scc(int n)
    26 {
    27     int i;
    28     scc_cnt = 0;
    29     s.clear();
    30     memset(sccno,0,sizeof(sccno));
    31     memset(vis,0,sizeof(vis));
    32     for(i=0; i<n; i++)dfs1(i);              //对所有顶点遍历,入栈
    33     for(i=n-1; i>=0; i--)if( !sccno[s[i]] ){//找强连通分量,找过了则不用找了
    34         scc_cnt++;                          //记录找到连通分量的个数
    35         dfs2(s[i]);
    36     }
    37 }
    38 int main()
    39 {
    40     //freopen("in.txt","r",stdin);
    41     int i,j,T,n,u,ver;
    42     int in0[maxn],out0[maxn];
    43     cin>>T;
    44     while(T--)
    45     {
    46         cin>>n;
    47         for(i=1; i<=n; i++)
    48         for(j=1; j<=n; j++){
    49             cin>>ver;
    50             if(ver==0)break;
    51             G[i-1].push_back(ver-1); //原图
    52             G2[ver-1].push_back(i-1);//逆向图
    53         }
    54         find_scc(n);                 //求连通分量
    55         for(i=1; i<=scc_cnt; i++)in0[i] = out0[i] = 1;//同一个连通分量所有点看成一个点
    56         for(u=0; u<n; u++)
    57         for(i=0; i<G[u].size(); i++){
    58             int v = G[u][i];
    59             if(sccno[i] != sccno[v]) in0[sccno[v]] = out0[sccno[u]] = 0;
    60         }
    61         int a = 0,b = 0;            //分别统计入度和出度为0的顶点个数
    62         for(i=1; i<=scc_cnt; i++){
    63             if(in0[i])a++;
    64             if(out0[i])b++;
    65         }
    66         int ans = max(a,b);         //取最大的输出
    67         if(scc_cnt == 1) ans = 0;   //只有一个连通分量,说明是强连通图,加0条边
    68         cout<<ans<<endl;
    69         for(i=0; i<=n; i++){G[i].clear();G2[i].clear();}//清空
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    SAP Cloud for Customer Sales Lead明细页面视图的UI模型
    如何基于SAP CDS view创建OData服务
    使用SAP HANA Web-based Development工具进行SQLScript练习
    SAP ABAP守护进程(ABAP Daemon)的实现方式
    使用SAP云平台Mobile Service开发移动应用
    SAP CRM WebClient UI Excel Export的运行时执行明细
    MySQL里面的子查询实例
    hash_hmac 签名
    redis单例模式写法
    jQuery 短信验证码倒计时
  • 原文地址:https://www.cnblogs.com/qiu520/p/3224811.html
Copyright © 2020-2023  润新知